题解:P3907 圈的异或

· · 题解

建一棵树,其余的边为非树边,则现在图中有树边和非树边。

那么一个环的异或和为非树边左端点到根的路径上边的异或和,异或上右端点到根的异或和,再异或上这条非树边的权值即可。

Code:

#include <bits/stdc++.h>
using namespace std;
#define int long long

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}

const int N=55;
int T,n,m,v[N],vis[N],flag=0,ans,dis[N]; 

struct nd{
    int to,w;
};
vector<nd> p[N];  

struct node{
    int x,y,val;
}q[N];

void dfs(int x,int fa){
    vis[x]=1;
    for(int i=0;i<p[x].size();i++){
        int y=p[x][i].to,w=p[x][i].w;
        if(vis[y]) continue;
        dis[y]=dis[x]^w;  
        dfs(y,x); 
    }
    return ;
}

void insert(){
    for(int i=1;i<=n;i++)
        p[i].clear(),vis[i]=0,dis[i]=0;
}
signed main(){
    T=read();
    while(T--){
        n=read(),m=read();
        insert();
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),w=read();
            q[i]=(node){x,y,w};
            p[x].push_back({y,w});
            p[y].push_back({x,w});
        }
        for(int i=1;i<=n;i++)
            if(!vis[i]) dfs(i,0);   
        int flag=0;
        for(int i=1;i<=m;i++)
            if(dis[q[i].x]^dis[q[i].y]^q[i].val)
                flag=1;
        if(!flag) cout<<"Yes\n";
        else cout<<"No\n";  
    }
    return 0;
}