codevs 5570 Xor(dfs)

题目描述 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;
}
发布了81 篇原创文章 · 获赞 2 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Loi_YZS/article/details/53172783