hdu 5833(欧拉路)

Posted AC菜鸟机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5833(欧拉路)相关的知识,希望对你有一定的参考价值。

The Best Path

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


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
 

 

Source
题意:有 n个湖泊m条河流,现在 Alice 要从某点出发走遍所有河流一次且仅一次,问Alice走过的点的异或最大值是多少?
题解:这题每条边要走且仅走一次,那么这明显就是个欧拉(回)路,先判断一下连通分量的个数,如果有多个就是 "Impossible",然后判断度为奇数的点的个数 ,如果不是0个或者2个,输出"Impossbie" ,如果度为奇数个数为 0 个,那么就是欧拉回路,那么就从度不为0且degree/2为奇数的每个点做异或,得到一个结果,得到的结果然后分别与每个点做异或,选择最大的.如果度为奇数的点是 2 个,那么每个点走的次数便是确定的,如果是度是偶数,那么degree/2为奇数的点参与异或,如果度为奇数,那么当(degree+1)/2为奇数时,此点参与异或。
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 100005;
int a[N];
int father[N];
int degree[N];
int _find(int x)
{
    if(x!=father[x]) father[x] = _find(father[x]);
    return father[x];
}
void Union(int a,int b)
{
    int x = _find(a);
    int y = _find(b);
    if(x==y) return ;
    father[x] = y;
}
void init(int n)
{
    for(int i=1; i<=n; i++)
    {
        father[i] = i;
        degree[i] = 0;
    }
}
int main()
{
    int tcase,n,m;
    scanf("%d",&tcase);
    while(tcase--)
    {
        scanf("%d%d",&n,&m);
        init(n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1; i<=m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            degree[u]++;
            degree[v]++;
            Union(u,v);
        }
        int ans = 0;
        for(int i=1; i<=n; i++)
        {
            if(degree[i]>0)
            {
                if(_find(i)==i) ans++;
            }
        }
        ///连通分量个数
        if(ans>1)
        {
            printf("Impossible\n");
            continue;
        }
        ans = 0;
        for(int i=1; i<=n; i++)
        {
            if(degree[i]%2!=0) ans++;
        }
        ///判断是否为欧拉路
        if(ans!=0&&ans!=2)
        {
            printf("Impossible\n");
            continue;
        }
        LL res = 0;
        if(ans==0)
        {
            for(int i=1; i<=n; i++)
            {
                int K = degree[i]/2;
                if(degree[i]!=0&&K%2==1){
                    res = res^a[i];
                }
            }
            LL MAX = -1;
            for(int i=1; i<=n; i++)
            {
                int K = degree[i]/2;
                if(degree[i]!=0){
                    MAX = max(MAX,res^a[i]);
                }
            }
            res = MAX;
        }
        else
        {
            for(int i=1; i<=n; i++)
            {
                int K = degree[i]/2;
                if(degree[i]%2==0&&K%2==1)
                {
                    res = res^a[i];
                }
                if(degree[i]%2==1)
                {
                    K = (degree[i]+1)/2;
                    if(K%2==1)
                        res = res^a[i];
                }
            }
        }
        printf("%lld\n",res);
    }
    return 0;
}

 

 
 

以上是关于hdu 5833(欧拉路)的主要内容,如果未能解决你的问题,请参考以下文章

欧拉路HDU3018

hdu 5883(欧拉路)

Play on Words HDU - 1116(欧拉路判断 + 并查集)

欧拉(回)路

HDU 5883 The Best Path (欧拉路或者欧拉回路)

HDU5883 The Best Path(并查集+欧拉路)