ZSTUOJ 4191 无向图找环 【dfs找环】

传送门
// 题意: 给定一副带权无向图, 问其中是否有异或值大于零的环存在.

// 思路: 直接dfs一遍找环就是了, 用sumxor[x] 表示到达这个点时的边权亦或和, 那么对于我们的起始点当然就是sumxor[st] = 0, 然后如何表示环上面的路径亦或和了, 假设是7 8 1 2 3 4 1, 从4返回1的时候如何表示1-4的环上亦或和了, 那就是sumxor[4] ^ sumxor[1] 那么就是除去即将到达的边的亦或和答案, 那么在^ 准备访问的边就可以判断是否有答案了..

AC Code

const int maxn = 1e5+5;
int cas=1;
int sumxor[maxn];
struct node {
    int to, next, w;
}e[maxn<<2];
int cnt , head[maxn], vis[maxn];
int n, m, flag;
void add(int u, int v, int w) {
    e[cnt] = node{v, head[u], w};
    head[u] = cnt++;
}

bool dfs(int u,int fa) {
    for (int i = head[u] ; ~i ; i = e[i].next) {
        int to = e[i].to;
        if (to == fa) continue;
        if (!vis[to]) {
            sumxor[to] = sumxor[u] ^ e[i].w;
            vis[to] = 1;
            if(dfs(to, u)) return true;
        }
        else {
            if ((sumxor[to] ^ sumxor[u] ^ e[i].w) > 0) {
                flag = 1;
                return true;
            }
        }
    }
    return false;
}

void solve()
{
    while(cin >> n >> m) {
        cnt = 0 ; Fill(head, -1);
        Fill(vis, 0);
        for (int i = 1 ; i <= m ; i ++) {
            int u, v, w;
            cin >> u >> v >> w;
            add(u, v, w);
            add(v, u, w);
        }
        flag = 0;
        sumxor[1] = 0;
        vis[1] = 1;
        dfs(1, -1);
        if (flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
}

你可能感兴趣的:(BFS/DFS搜索or暴力模拟)