問題
①複数の地点が与えられて、それぞれの地点に値を持つ。
②また地点によっては道路で結ばれていて、
道路として結ばれている2次元配列が与えられる。
③ユーザは地点0から始まり、地点0のスコアを持つ。
④地点0から結ばれている地点に何度も行くことができ、
移動したときのスコアは、今まで持つスコアと移動した地点のスコアのXORとなる。
⑤このとき、最大となるスコアを求める。
解き方
ぱっとみたときに何度も同じ地点を行き来することができるので、
全探索も浮かびにくい。
手掛かりとなる制約条件がないか例を出してシミュレーションしてみると、
ある地点に移動したとき、持っているスコアは1度しか現れないことがわかる。
つまり幅優先探索を行い、
地点とスコアの2次元配列を作成し
通ったことがあるかないかを判定すれば収束させることができる。
計算量はO(50*50*1024=2.5*10^6)なのでOK.
コード
class XorTravelingSalesman {
public: int maxProfit(vector<int> cityValues, vector<string> roads) {
int ans=cityValues[0];
bool visited[50][1023];
queue< pair<int,int> > q;
FORE(i,0,50)FORE(j,0,1023)visited[i][j]=false;
q.push(make_pair(0,cityValues[0]));
visited[0][cityValues[0]]=true;
while(!q.empty()){
int cur=q.front().first;
int value=q.front().second;
q.pop();
FORE(i,0,cityValues.size()){
if(i==cur)continue;
int tmpvalue=value^cityValues[i];
if( (roads[cur][i]=='Y' || roads[i][cur]=='Y') && !visited[i][tmpvalue]){
ans=max(ans,tmpvalue);
visited[i][tmpvalue]=true;
q.push(make_pair(i,tmpvalue));
}
}
}
return ans;
}
};
public: int maxProfit(vector<int> cityValues, vector<string> roads) {
int ans=cityValues[0];
bool visited[50][1023];
queue< pair<int,int> > q;
FORE(i,0,50)FORE(j,0,1023)visited[i][j]=false;
q.push(make_pair(0,cityValues[0]));
visited[0][cityValues[0]]=true;
while(!q.empty()){
int cur=q.front().first;
int value=q.front().second;
q.pop();
FORE(i,0,cityValues.size()){
if(i==cur)continue;
int tmpvalue=value^cityValues[i];
if( (roads[cur][i]=='Y' || roads[i][cur]=='Y') && !visited[i][tmpvalue]){
ans=max(ans,tmpvalue);
visited[i][tmpvalue]=true;
q.push(make_pair(i,tmpvalue));
}
}
}
return ans;
}
};