hdoj 5883 The Best Path

xiaoxiao2021-02-28  78

题目链接: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; }

转载请注明原文地址: https://www.6miu.com/read-64836.html

最新回复(0)