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

本文探讨了一个特定的图论问题,即如何通过合理选择起点来最大化遍历所有边后的点值异或结果。讨论了欧拉回路和通路的区别,并提供了一种有效的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要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

 

转载于:https://www.cnblogs.com/liuweimingcprogram/p/6021106.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值