HDU5883 The Best Path(欧拉回路)

来源:互联网 发布:网络流行关键词 编辑:程序博客网 时间:2024/05/22 12:17

The Best Path

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 712    Accepted Submission(s): 308


Problem Description
Alice is planning her travel route in a beautiful valley. In this valley, there areN 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 integert, 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
23 23451 22 34 312341 22 32 4
 

Sample Output
2Impossible
题意:有N个点,每个点的值ai,M条路,问能不能经过所有的路有且仅有一次,如果能,输出经过的点的异或的最大值。
思路:
异或符合交换律,所以异或和顺序无关。
符合题意的有两种情况:
1.欧拉回路:如果每个点的度都是偶数,这时候,起点会被异或多一次,所以枚举一下就能求出最大值。
2.欧拉通路:有且仅有两个点的度是奇数,这两个点就是起点和终点,除了起点和终点,其他点的度如果是2的奇数倍,就要被计入结果,
因为2的偶数倍的点会被经过偶数次,2的奇数倍的点会被经过奇数次。
#include <bits/stdc++.h>using namespace std;#define maxn 100010int a[maxn], N, M, res, b[maxn];bool flag;int main(){    int i, T, u, v, res;    scanf("%d", &T);    while(T--){        res = 0;        scanf("%d %d", &N, &M);        memset(b, 0, sizeof b);        for(i = 1;i <= N;i++){            scanf("%d", &a[i]);            res ^= a[i];        }        for(i = 0;i < M;i++){            scanf("%d %d", &u, &v);                b[u]++, b[v]++;        }        int q = 0;        flag = 1;        for(i = 1;i <= N;i++)            if(b[i]%2==1) q++;        if(q==0) {            int tmp = res;            res ^= a[1];            for(i = 2;i <= N;i++)                res = max(res, tmp^a[i]);        }else if(q==2){            for(i = 1;i <= N;i++) {                if((b[i]/2)%2!=1&&b[i]%2==0)                    res ^= a[i];            }        }else flag = 0;        if(flag) printf("%d\n", res);        else printf("Impossible\n");    }}
0 0
原创粉丝点击