The Best Path---hdu5883(欧拉路径)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5883

题意:n 个点 条无向边的图,找一个欧拉通路/回路使得这个路径所有结点的异或值最大。

先判断是否含有欧拉路径,如果存在的话有两种情况,有起点和终点不同的欧拉路径,这样我们只需把经过奇数次的点的权值异或起来即可;

还有就是起点和终点相同的欧拉回路;我们在原来的基础上枚举出一个起点,使得结果最大即可;

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define met(a, b) memset(a, b, sizeof(a))
#define N 100005
#define INF 0x3f3f3f3f
typedef long long LL;

int du[N], n, a[N];

int Judge()
{
    int odd = 0, ans = 0;
    for(int i=1; i<=n; i++)
    {
        if(du[i]&1)
            odd++;
    }

    if(odd !=0 && odd != 2)///度数为奇数的点只有是这两种情况下才存在欧拉路径;
        return -1;

    for(int i=1; i<=n; i++)
    {
        du[i] = (du[i]+1)/2;///经过一个点的次数;
        if(du[i]&1)///当经过偶数次时异或结果为0,所以只需异或奇数即可;
            ans ^= a[i];
    }
    if(odd == 0)///当度数都为偶数时,说明存在欧拉回路,我们只需枚举起点,保存最大值即可;
    {
        for(int i=1; i<=n; i++)
            ans = max(ans, ans^a[i]);
    }
    return ans;
}

int main()
{
    int T, m;
    scanf("%d", &T);
    while(T--)
    {
        met(du, 0);

        scanf("%d %d", &n, &m);

        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);
            du[u] ++; du[v] ++;
        }

        int ans = Judge();

        if(ans == -1) puts("Impossible");
        else printf("%d
", ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5891515.html