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