hdu 5883 (欧拉路,青岛网络赛)

本文探讨了一道经典的图论问题——通过所有边的欧拉路径寻找最大异或和。针对n个节点m条边的图,文章提出了解决方案,并通过代码实现验证了算法的有效性。

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

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

n个湖泊,m个河流连着,要从一个湖泊出发,经过所有河流,没经过一个湖泊就有异或上ai,问异或和最大是多少?如果不能走完所有河流,输出Impossible。

分析:

显然是欧拉路问题,如果能完成,那么肯定是欧拉路,先判断连通。如果连通并且所有点的度都是偶数,那么就可以构成欧拉回路。如果两个奇度点,那么能构成欧拉路,从一个奇度点出发到另一个奇度点,这是答案是确定的。如果都是偶数度,那么枚举起点,取最大值即可。

代码:

#include<bits/stdc++.h>
using namespace std;

const int N=100000+10;

int fa[N],in[N],a[N];
int findfa(int x) {
    return x==fa[x]?x:fa[x]=findfa(fa[x]);
}

int main() {
    //freopen("f.txt","r",stdin);
    int T,n,m,u,v;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)fa[i]=i;
        memset(in,0,sizeof(in));
        int ans=0,num=0;
        for(int i=1; i<=n; i++)scanf("%d",&a[i]);
        for(int i=0; i<m; i++) {
            scanf("%d%d",&u,&v);
            in[u]++;
            in[v]++;
            int x=findfa(u),y=findfa(v);
            if(x!=y)fa[x]=y;
        }
        for(int i=1; i<=n; i++)if(findfa(i)==i)num++;
        if(num>1) {
            printf("Impossible\n");
            continue;
        }
        num=0;
        for(int i=1; i<=n; i++) {
            if(in[i]&1)num++;
            else in[i]/=2; //因为入度出度只算一次
        }
        for(int i=1; i<=n; i++) {
            if(in[i]&1)ans^=a[i]; //只有奇数异或才有贡献。
        }
        if(num==0||num==2) {
            if(num==2) {
                printf("%d\n",ans);
            } else {
                int res=0;
                for(int i=1; i<=n; i++)
                    res=max(res,ans^a[i]);
                printf("%d\n",res);
            }
        } else printf("Impossible\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值