题意:多组输入,先是两个整数N和M分别表示N个湖和M条河,然后N个数,表示这个N个湖的权值,然后M组数,表示连接第u个和第v个湖的河。现在alice从某一个湖出发,想要经过所有的河,如果可行的话,每经过一个湖异或其权值,不行的话输出“impossible”。
思路:把湖看作点,把河看作边,题目就变成了无向图所有边的遍历,可以使用欧拉图(欧拉回路和欧拉路径),就只需要存储每个点的度,然后遍历所有的点,如果奇数的度为两个则为欧拉路径、为零个则为欧拉回路,其他则无法形成欧拉图。根据异或的定义,两个数如果相同则为零,所以如果某个点的度除二(无向图的度包括入度和出度)为。
欧拉路径:因为起点和终点相较其他点分别少一个入度和一个出度,所以在判定的时候可以采用((度+1)/2)%2(对其他点度来说+1再/2不影响结果)来判断这个点是否需要异或,然后输出答案。
欧拉回路:相较于欧拉路径,欧拉回路的起点和终点是相同的,因此根据题意我们只需要在欧拉路径的基础上确定那个点为起点得到的答案最大就可以了,遍历所有点就好了。
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[100010],du[100010];
int main()
{
int n,t,m,u,v;
cin>>t;
while(t--)
{
int cnt=0,ans=0;
memset(du,0,sizeof(du));
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
du[u]++;
du[v]++;
}
for(int i=1;i<=n;i++)
if(du[i]%2) cnt++;
if(cnt==0||cnt==2)
{
if(cnt==0)
{
for(int i=1;i<=n;i++)
if(((du[i]+1)/2)%2) ans^=a[i];
int mx=0;
for(int i=1;i<=n;i++)
mx=max(ans^a[i],mx);
ans=mx;
}
else
{
for(int i=1;i<=n;i++)
if(((du[i]+1)/2)%2) ans^=a[i];
}
cout<<ans<<endl;
}
else
cout<<"Impossible"<<endl;
}
return 0;
}