题意:当每条河只能走一遍而且能遍历所有湖的情况下,输出每个湖的值的最大异或值,如果不存在这种情况输出impossible。
思路:我强大的队友画图找出了规律。。。tql
对于一个湖,算出他出度入度的总和之后,遍历一遍看他有几个奇数,如果有两个奇数或者没有奇数的话就说明可以在每条边都遍历一遍的情况下走遍所有的湖,其他情况就是不能遍历所有的湖直接输出impossible。当全是偶数边的时候,说明是环,那么肯定会回到起点的位置,那么起点的位置就多异或了一遍,最后还得再异或一遍起点的位置,那么我们本题是在任意起点出发,所以我们要遍历所有湖,然后拿我们算好的异或值再异或一下湖的数取最大值,如果有两个奇数边的话就没有回到起始点的情况,所以直接输出我们算的异或值就行了。
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
ll d[100005],a[100005];
int n,m;
void sove(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
d[i]=0;
}
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
d[a]++;
d[b]++;
}
int con=0;
for(int i=1;i<=n;i++){
if(d[i]&1)con++;
}
if(con!=0&&con!=2){
cout<<"Impossible"<<endl;
return ;
}
ll ans=0;
for(int i=1;i<=n;i++){
int tmp=(d[i]+1)/2;//因为我们算的是出度+入度,所以我们每次算一个湖异或几遍的时候先/2.
while(tmp--){
ans^=a[i];
}
}
if(con==2){//当有2个奇数说明不能回到起始点直接输出异或值
cout<<ans<<endl;
return ;
}
//如果全是偶数说明会回到起点,那么列举一下我们算出来的数和每个起点的值异或起来的数取最大。
int res=0;
for(int i=1;i<=n;i++){
if(d[i]){
int num=ans^a[i];
res=max(res,num);
}
}
cout<<res<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie() ,cout.tie() ;
int t=1;
cin>>t;
while(t--){
sove();
}
return 0;
}