【HDU 5883】The Best Path(欧拉路+异或和)
题目大意:
n个点m条边,问m条边构成的是否为欧拉路。
是的话输出路径上所有点的异或和,每个点经过几次异或几次。
首先判欧拉路,bfs或者并查集
如果是欧拉路径而不是回路,答案是唯一的。
回路的情况,起点不同会的导致异或结果不同,枚举起点找个最大的结果就行了。
每个点被异或只与它的度的奇偶以及它是否是起点有关。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 112345;
int arr[maxn];
int fnd(int x){
return x == arr[x] ? x : arr[x] = fnd(arr[x]);
}
void join(int x,int y){
x = fnd(x),y = fnd(y);
if(x != y)
arr[x] = y;
}
int val[maxn],ind[maxn];
int cal(int n){
int bio = 0,odd = 0;
for(int i=1;i<=n;i++){
if(arr[i] == i && ind[i] != 0)
bio++;
odd += ind[i] % 2;
}
if(bio >= 2)
return -1;
if(bio == 0){
return *max_element(val+1,val+1+n);
}
if(odd == 0){
int all = 0,ret = 0;
for(int i=1;i<=n;i++){
if((ind[i]/2) & 1) all ^= val[i];
}
for(int i=1;i<=n;i++){
if(ind[i])
ret = max(ret,all ^ val[i]);
}
return ret;
}
if(odd == 2){
int ret = 0;
for(int i=1;i<=n;i++){
if(ind[i]){
if(ind[i] % 2){
if(((ind[i]+1)/2)&1) ret ^= val[i];
}
else{
if((ind[i]/2)&1) ret ^= val[i];
}
}
}
return ret;
}
return -1;
}
int main(){
int T;
scanf("%d",&T);
int n,m;
while(T-- && ~scanf("%d %d",&n,&m)){
memset(ind,0,sizeof(ind));
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
arr[i] = i;
}
int x,y;
for(int i=0;i<m;i++){
scanf("%d %d",&x,&y);
join(x,y);
ind[x]++,ind[y]++;
}
int cnt = cal(n);
if(cnt == -1){
puts("Impossible");
}
else{
printf("%d\n",cnt);
}
}
return 0;
}