【和状态有关的搜索】

【和状态有关的搜索】

考虑不重复/不死循环的优化
一般都在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;
}
posted @ 2025-06-14 23:08  White_ink  阅读(10)  评论(0)    收藏  举报