hdoj 5883 The Best Path

来源:互联网 发布:模块化数据机房 编辑:程序博客网 时间:2024/06/08 14:30

题目链接:The Best Path


题目大意:给你n个点,m条边,然后每条边连接某两个点,可以自环,每个点有一个权值,问能不能有路径经过所有的边且只经过一次,路径的路径权值为经过的所有的点的权值依次异或起来,问最大的路径权值为多少


题目思路:首先我们找的路径是一个欧拉路径,而且所有的边得都在一个集合里面,也就是给的边得两个点一定在一个集合里面,如果有不在集合的边,直接输出Impossible,这个可以拿并查集取判断(实际上欧拉路也就是一个并查集)然后要开始找度数(入度加出度)为奇数的个数,如果有两个,证明有欧拉路径且只是欧拉路径,所有在集合的点的权值异或起来即可,否则证明有欧拉回路,找一个点作为开始点多异或依次这个点就可以了,具体看代码(代码应该有bug,题目数据水了)

#include <bits/stdc++.h>using namespace std;const int maxn = 100005;int t,n,m,x,y,va[maxn],tim[maxn],pre[maxn];int Find(int x){    if(x == pre[x]) return x;    return pre[x] = Find(pre[x]);}void join(int x,int y){    int p = Find(x),q = Find(y);    if(p != q) pre[p] = q;}void init(){    for(int i = 0;i <= maxn;i++)        pre[i] = i;}int main(){    scanf("%d",&t);    while(t--){        init();        memset(va,0,sizeof(va));        memset(tim,0,sizeof(tim));        scanf("%d%d",&n,&m);        for(int i = 1;i <= n;i++)            scanf("%d",&va[i]);        while(m--){            scanf("%d%d",&x,&y);            tim[x]++;            tim[y]++;            join(x,y);        }        int p = Find(y);        int ss = 0;        int flag = 0;        int ans = 0;        for(int i = 1;i <= n;i++){            if(Find(i) != p&&tim[i] > 0)                {puts("Impossible");flag = 1;break;}        }        for(int i = 1;i <= n;i++){            if(tim[i]%2) ss++;            if(((tim[i]+1)/2)%2 == 1) ans ^= va[i];        }        if(flag) continue;        if(ss == 2) printf("%d\n",ans);        else if(ss == 0){            int maxx = -1;            for(int i = 1;i <= n;i++){                if(pre[i] != i)                maxx = max(maxx,ans^va[i]);            }            printf("%d\n",maxx);        }        else puts("Impossible");    }    return 0;}

0 0
原创粉丝点击