HDU - 5883 The Best Path(欧拉路径)

The Best Path

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


 

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 P0→P1→...→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 (N≤100000) and M (M≤500000), as described above. The i-th line of the next N lines contains an integer ai(∀i,0≤ai≤10000) 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

Source

2016 ACM/ICPC Asia Regional Qingdao Online

Recommend

wange2014

题意:一张无向图,每个点都有点权值,找一条欧拉路径,使所有点的点权的异或和最大,输出这个最大值

思路:偶数的相同的数异或和为0,奇数个相同的数的异或和为这个数,先判断一下是否存在欧拉回路,首先这张图必须连通,用并查集判断一下就行了(但看其他博客里都没有这个判断),记录每个点的度数,当奇数度点为0和2时,存在欧拉路径,任意点在欧拉路径中出现的次数为(度数+1) / 2,但当全为偶数度顶点时,起点多出现一次,把每一个点为起始顶点的情况枚举一遍取最大值即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MAXN = 100005;
int de[MAXN],pre[MAXN],val[MAXN];
int findset(int x)
{
    if(x == pre[x]) return x;
    else findset(pre[x]);
}
int main(void)
{
    int T,n,m,u,v;
    int cnt_k,cnt_d,f1,f2,fu,fv;
    int ans,Ans;
    cin >> T;
    while(T--) {
        memset(de,0,sizeof(de));
        scanf("%d %d",&n,&m);
        for(int i = 1; i <= n; i++) {
            scanf("%d",&val[i]);
            pre[i] = i;
        }
        while(m--) {
            scanf("%d %d",&u,&v);
            de[u]++;de[v]++;
            fu = findset(u),fv = findset(v);
            if(fu != fv) pre[fv] = fu;
        }
        cnt_d = 0,cnt_k = 0;
        for(int i = 1; i <= n; i++) {
            if(de[i] % 2) cnt_d++;
            if(pre[i] == i) cnt_k++;
        }
        if(cnt_k > 1 || cnt_d > 2 || cnt_d == 1) {
            printf("Impossible\n");
        }
        else {
            if(cnt_d == 2) {
                ans = 0;
                for(int i = 1; i <= n; i++) {
                    if(((de[i] + 1) / 2) % 2) ans ^= val[i];
                }
                printf("%d\n",ans);
            }
            else {
                Ans = 0,ans = 0;
                for(int i = 1; i <= n; i++) {
                    if(((de[i] + 1) / 2) % 2) ans ^= val[i];
                }
                for(int i = 1; i <= n; i++) {
                    Ans = max(Ans,ans ^ val[i]);
                }
                printf("%d\n",Ans);
            }
        }
    }
    return 0;
}
/*
2
3 2
3
4
5
1 2
2 3
4 3
1
2
3
4
1 2
2 3
2 4
*/

猜你喜欢

转载自blog.csdn.net/GYH0730/article/details/81674062