http://acm.hdu.edu.cn/showproblem.php?pid=5883
题目大意:
有N个湖M条河 Alices规划行程一睹大自然的风光 每个湖有一个权值 她想经过每条河且只走一次 每经过一个湖泊就将琥珀的权值异或 求最终异或值的最大值
分析:
每条边只经过一次走遍全图 这是欧拉回路或欧拉通路的问题 欧拉路首先图要求是联通的(并查集即可) 其次奇度节点为0或2个 一个节点进一次出一次 度 - 2 贡献一次异或 欧拉通路时起点和终点贡献+1 欧拉回路时起点(终点)贡献+1 因此回路时枚举一下起点就好
AC代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;
#define lson 2*i
#define rson 2*i+1
#define LS l,mid,lson
#define RS mid+1,r,rson
#define UP(i,x,y) for (i=x;i<=y;i++)
#define DOWN(i,x,y) for (i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 1000005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define lowbit(x) (x&-x)
int pre[N];
int a[N];
int val[N];
int find(int x){
int r=x;
W(pre[r]!=r){
r=pre[r];
}
int i=x;
int temp;
W(i!=r){
temp=pre[i];
pre[i]=r;
i=temp;
}
return r;
}
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
pre[fx]=fy;
}
}
int main()
{
int t;
int n,m;
int x,y;
int i,j;
//freopen("data","r",stdin);
scanf ("%d",&t);
W(t--){
memset(a,0,sizeof(a));
memset(pre,0,sizeof(pre));
scanf("%d%d",&n,&m);
UP(i,1,n) scanf ("%d",&val[i]);
UP(i,1,n) pre[i]=i;
UP(i,1,m){
scanf("%d%d",&x,&y);
join(x,y);
a[x]++;
a[y]++;
}
int flag=1;
int count=0;
int ss=0;
int ans=0;
UP(i,1,n)
if(find(i)==i) ss++;
if(ss>1) flag=0;
else{
UP(i,1,n)
if(a[i]%2!=0) count++;
if(count!=0&&count!=2)
flag=0;
else{
UP(i,1,n)// 通路时
if(((a[i]+1)/2)%2) ans^=val[i];
int temp=0;
if(!count){
UP(i,1,n)// 枚举起点
temp=max(temp,ans^val[i]);
ans=temp;
}
}
}
if(flag)
printf("%d\n",ans);
else
printf("Impossible\n");
}
return 0;
}