题目:http://acm.hdu.edu.cn/showproblem.php?pid=5883
题意:
n个湖泊,m个河流连着,要从一个湖泊出发,经过所有河流,没经过一个湖泊就有异或上ai,问异或和最大是多少?如果不能走完所有河流,输出Impossible。
分析:
显然是欧拉路问题,如果能完成,那么肯定是欧拉路,先判断连通。如果连通并且所有点的度都是偶数,那么就可以构成欧拉回路。如果两个奇度点,那么能构成欧拉路,从一个奇度点出发到另一个奇度点,这是答案是确定的。如果都是偶数度,那么枚举起点,取最大值即可。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100000+10;
int fa[N],in[N],a[N];
int findfa(int x) {
return x==fa[x]?x:fa[x]=findfa(fa[x]);
}
int main() {
//freopen("f.txt","r",stdin);
int T,n,m,u,v;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)fa[i]=i;
memset(in,0,sizeof(in));
int ans=0,num=0;
for(int i=1; i<=n; i++)scanf("%d",&a[i]);
for(int i=0; i<m; i++) {
scanf("%d%d",&u,&v);
in[u]++;
in[v]++;
int x=findfa(u),y=findfa(v);
if(x!=y)fa[x]=y;
}
for(int i=1; i<=n; i++)if(findfa(i)==i)num++;
if(num>1) {
printf("Impossible\n");
continue;
}
num=0;
for(int i=1; i<=n; i++) {
if(in[i]&1)num++;
else in[i]/=2; //因为入度出度只算一次
}
for(int i=1; i<=n; i++) {
if(in[i]&1)ans^=a[i]; //只有奇数异或才有贡献。
}
if(num==0||num==2) {
if(num==2) {
printf("%d\n",ans);
} else {
int res=0;
for(int i=1; i<=n; i++)
res=max(res,ans^a[i]);
printf("%d\n",res);
}
} else printf("Impossible\n");
}
return 0;
}