HDU 5883 F - The Best Path 欧拉通路 & 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值。

 

首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点。

欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点。

 

关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一。

因为每两个度就表示:一进一出,度数为2,所以才访问一次。

奇数度的话,剩下的那一个度就是用来出或则进的,

 

然后如果有一个点的度数是0,则可以说明图不联通,

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e5 + 20;
int a[maxn];
int Degree[maxn];
void init(int n) {
    for (int i = 1; i <= n; ++i) {
        Degree[i] = 0;
    }
}
void work() {
    int n, m;
    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]++;
    }
    int root = 0;
    root = 0;
    for (int i = 1; i <= n; ++i) {
        root += Degree[i] & 1;
        if (Degree[i] == 0) {
            printf("Impossible\n");
            return;
        }
    }
    if (!(root == 0 || root == 2)) {
        printf("Impossible\n");
        return;
    }
    int ans = 0;
    int tans = 0;
    for (int i = 1; i <= n; ++i) {
        int tim = Degree[i] / 2 + (Degree[i] & 1);
        tim &= 1;
        tans ^= a[i] * tim;
    }
    if (root == 0) {
        for (int i = 1; i <= n; ++i) {
            int gg = tans ^ a[i];
            ans = max(ans, gg);
        }
    } else {
        ans = tans;
    }
    printf("%d\n", ans);
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
//    printf("%d\n", 1  ^ 3 ^ 4 ^ 5 ^ 6);
    int t;
    scanf("%d", &t);
    while (t--) work();
    return 0;
}
View Code

 

posted on 2016-11-01 21:36  stupid_one  阅读(239)  评论(0编辑  收藏  举报

导航