【和状态有关的搜索】
【和状态有关的搜索】
考虑不重复/不死循环的优化
一般都在1e3这个数据范围内/位运算/状态可压缩->可暴力地设状态
XOR Shortest Walk
https://atcoder.jp/contests/abc410/tasks/abc410_d
题目大意
一个有向图,路径有权值
求1到n的所有路径中权值异或的最小值
思路
看到数据范围 n,m<=1e3 w[i]<2^10=1024
-可n方遍历 可二维设状态
->大体思路为从1开始遍历每条边到n 求每条路径->如何遍历每条路径?
->因为异或超不过2^10 每个点都有0~2^10种状态->可以设
设状态:dp[i][j] 到达顶点i时异或值为j是否存在
看能否从dp[1][0]转移到dp[n][0~(1<<10)]
->加状态之后 不用担心环->遍历每个点每条边 复杂度也为O(NM)
代码
int n,m;
vector<PII> g[N];
int val[N];
bool dp[N][1<<10];
int st[N];
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({v,i});
val[i]=w;
}
queue<PII> q;
dp[1][0]=1;
q.push({1,0});
while(q.size()){
auto t=q.front();
q.pop();
int pos=t.first;
int num=t.second;
for(auto son:g[pos]){
int pos_=son.first,num_=num^val[son.second];
//如果该状态没到达过 (可避免环!
if(!dp[pos_][num_]){
dp[pos_][num_]=1;
q.push({pos_,num_});
}
}
}
//找最小的
for(int i=0;i<(1<<10);i++){
if(dp[n][i]){
cout<<i<<endl;
return;
}
}
cout<<-1<<endl;
}