The Best Path

Problem Description
Alice is planning her travel route in a beautiful valley. In this valley, there are  N  lakes, and  M  rivers linking these lakes. Alice wants to start her trip from one lake, and enjoys the landscape by boat. That means she need to set up a path which go through every river exactly once. In addition, Alice has a specific number ( a1,a2,...,an ) for each lake. If the path she finds is  P0P1...Pt , the lucky number of this trip would be  aP0XORaP1XOR...XORaPt . She want to make this number as large as possible. Can you help her?
 

Input
The first line of input contains an integer  t , the number of test cases.  t  test cases follow.

For each test case, in the first line there are two positive integers  N (N100000)  and  M (M500000) , as described above. The  i -th line of the next  N  lines contains an integer  ai(i,0ai10000)  representing the number of the  i -th lake.

The  i -th line of the next  M  lines contains two integers  ui  and  vi  representing the  i -th river between the  ui -th lake and  vi -th lake. It is possible that  ui=vi .
 

Output
For each test cases, output the largest lucky number. If it dose not have any path, output "Impossible".
 

Sample Input
  
  
2 3 2 3 4 5 1 2 2 3 4 3 1 2 3 4 1 2 2 3 2 4
 

Sample Output
  
  
2 Impossible

/*欧拉路的判断, 寻找最多的幸运数; */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int big = 1e5 + 7; int a[big];//每个节点的度数; int  b[big];//湖的编号; int z[big], e, f, flag; bool judge(int n)//判断是否为欧啦路; {     int sum = 0, h;     for(int i = 1; i <= n; i ++)         if(z[i] == i) sum ++;     if(sum != 1) return false;     sum = flag = 0;     for(int i = 1; i <= n; i ++)     {         if(a[i]&1)         {             sum ++;             a[i] ++;         }         h = a[i]/2;         if(!(h&1)) b[i] = 0;         }     if(sum != 0 && sum != 2) return false;     if(sum == 2) flag = 1;     return true; } void G(int n)//湖的标号; {     for(int i = 1; i <= n; i ++)         z[i] = i; } int Find(int key) {     int s = key;     while(s != z[s])         s = z[s];     int j = key, e;     while(j != s)     {         e = z[j];         z[j] = s;         j = e;     }     return s; } int main() {     int t, n, m, u, v, p, q;     scanf("%d", &t);     while(t --)     {         scanf("%d %d", &n, &m);         memset( a, 0, sizeof( a));         for(int i = 1; i <= n; i ++)             scanf("%d", &b[i]);         G(n);//湖的编号;         for(int i = 1; i <= m; i ++)         {             scanf("%d %d", &u, &v);             a[u] ++;             a[v] ++;             p = Find(u);             q = Find(v);             if(p == q) continue;             if(p > q) swap( p, q);             z[q] = p;         }         if(judge(n))         {             int temp = b[1], ans = 0;             for(int i = 2; i <= n; i ++)                 temp = temp xor b[i];             if(flag) ans = temp;             else             {                 for(int i = 1; i <= n; i ++)                     ans = max( ans, temp xor b[i]);             }             printf("%d\n", ans);         }         else printf("Impossible\n");     }     return 0; }

#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; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值