题目描述 Description
给出无向图G,边(Ai,Bi) 的权是Ci,判断下列性质是否成立
对于任意圈C,其边权的异或和是0输入描述 Input Description
第1 行,1 个整数T,表示数据的组数。
每组数据第1 行,2 个整数N,M,表示图G 点和边的数量。
M 行,每行3 个整数Ai,Bi,Ci输出描述 Output Description
对每个数据输出一行,“Yes” 或者“No”样例输入 Sample Input
2
3 3
1 2 1
2 3 2
3 1 3
1 1
1 1 1样例输出 Sample Output
Yes
No数据范围及提示 Data Size & Hint
• 对于50% 的数据,N,M <= 20
• 对于100% 的数据,1 <= N,M <= 50; 1 <= Ai,Bi <= N; 0 < =Ci < 2^16
题解:dfs找环,每找到一个环就判断一下异或和是不是零,如果有一个环异或和不是零就输出No。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN=50;
int first[MAXN],nxt[MAXN<<1];
int n,m,tot,d[MAXN];//d数组存的dfs到第i个点的异或和
bool vis[MAXN];
struct edge
{
int from,to,cost;
}es[MAXN<<1];
void init()
{
memset(first,-1,sizeof(first));
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
tot=0;
}
void build(int f,int t,int d)
{
es[++tot]=(edge){f,t,d};
nxt[tot]=first[f];
first[f]=tot;
}
bool dfs(int s)//dfs找环
{
vis[s]=1;
for(int i=first[s];i!=-1;i=nxt[i])
{
int v=es[i].to;
if(vis[v])//找到一个环
{
if(d[v]==(d[s]^es[i].cost)) continue;//如果异或和为零
else return 0;
}
d[v]=d[s]^es[i].cost;//当前点的异或和等于上一个点的异或和异或这条边
if(!dfs(v)) return 0;
}
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();//每次都要初始化
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
build(a,b,c);
build(b,a,c);
}
bool flag=0;
for(int i=1;i<=n;i++)
if(!vis[i]&&!dfs(i))//dfs
{
flag=1;
break;
}
if(flag) printf("No\n");
else printf("Yes\n");
}
return 0;
}