欧拉回路
对于一个图G存在这样一条路径,使它在所有边都经过一次,称这样的路径为欧拉路径。若该路径是一个圈,则称为是欧拉回路;
具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉路径但不具有欧拉回路的称为半欧拉图。
无向图存在欧拉回路的充要条件
当且仅当这个图的所有顶点的度数是偶数,且该图是连通图。
无向图含有欧拉通路的充要条件
当且仅当这个图有零个或两个奇数度的结点,且该图是连通图。
有向图存在欧拉回路的充要条件
所有顶点的 入度 和 出度 的和是 偶数,且该图是连通图。
有向图含有欧拉通路的充要条件
起始点s 的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度,且该图是连通图。
题意:n个点m条无向边的图,找一个欧拉通路/回路,下标是p1,p2,p3…pt,然后使得ap1XORap2XOR…XORapt这个值最大。
思路:
首先要判断一下这个图是不是联通的,用并查集就好了,然后有个注意点就是可能是单个独立点;
然后再判断是不是欧拉通路,不是也不行;
最后计算,最后如果是欧拉回路还要找一个最大起点(终点)。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
int pre[N];
int a[N];
int in[N];
int Find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(pre[i]!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void Union(int x,int y)
{
int xx=Find(x);
int yy=Find(y);
if(xx!=yy)
pre[xx]=yy;
}
void init()
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
pre[i]=i;
in[i]=0;
}
}
int main()
{
int T,m,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
in[x]++;
in[y]++;
Union(x,y);
}
int flag=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i&&in[i])
flag++;
if(flag==2)
break;
}
if(flag==2)
{
puts("Impossible");
continue;
}
int res,num=0;
for(int i=1;i<=n;i++)
{
if(in[i]&1)
num++;
}
if(!(!num||num==2))
{
puts("Impossible");
continue;
}
int ans=0;
for(int i=1;i<=n;i++)
{
res=in[i];
if(res%2)
{
res/=2;
if((res+1)%2)
ans^=a[i];
}
else
{
res/=2;
if(res%2)
ans^=a[i];
}
}
//printf("%d\n",ans);
if(!num)
{
res=ans;
for(int i=1;i<=n;i++)
{
res=max(res,ans^a[i]);
}
printf("%d\n",res);
}
else
printf("%d\n",ans);
}
return 0;
}