HDU5883 The Best Path——欧拉路(异或)

点这里


题意: T组数据,n个湖(即点),m条河(即边),并且每个点都有一个权值。如果这个图能构成欧拉路(包括回路),求从起点异或到终点的值中的最大值。
题解:

  • 连通性。 由于题目性质,这道题中的点都是相互连通的,不需要另外判断。
  • 欧拉路(回路)。 判断所有点的度数即可:欧拉回路——所有点都是偶点,欧拉路——只有两个奇点,其他全为偶点。
  • 异或结果。 实际上没到一个点都要求一遍异或,那为什么可以求最大值呢?而且欧拉回路中虽然边不重复,但是点会重复,那么我们一个点需要求几次异或呢?
    • (deg[i] + 1) / 2 % 2。 试想,如果到达某个点偶数次,某个权值需要异或偶数次,a ^ a = 0,就变得没有意义了。所有我们只需要找到经过奇数次的点,但请注意是 (deg[i] + 1) / 2 % 2 而不是deg[i] % 2 。为什么?在欧拉路中,起点和终点的度数一定是奇数,例如1,那么经过次数为1;途中的点的度数一定为偶数,例如2,那么经过次数为1。所以我们要求的是某个个点的经过次数,而不是度数本身。而经过次数与度数的关系即为:次数 = (deg[i] + 1) / 2
    • 最大值。 那既然每经过一个点都要异或一次,何来最大值呢?欧拉回路。 如果图是欧拉回路的话,我们可以将图中原本一个经过偶数次的点作为起点,思考一下成为起点之后它还是经过偶数次吗?因为有可能可以改变某个点的经过次数,而经过次数决定了这个权值的异或是否有意义,从而影响了最后的结果。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

int T, n, m, a, b;
int w[N], deg[N];
int main(){
	scanf("%d", &T);while(T--){
		scanf("%d%d", &n, &m);
		memset(deg, 0, sizeof deg);
		for(int i = 1; i <= n; i++)	scanf("%d", w + i);
		while(m--){
			scanf("%d%d", &a, &b);
			deg[a]++, deg[b]++;
		}
		int sum = 0, ans = 0;
		for(int i = 1; i <= n; i++) if(deg[i] % 2)	sum++;
		if(sum != 0 && sum != 2){	printf("Impossible\n");	continue;}
		for(int i = 1; i <= n; i++)	if((deg[i] + 1) / 2 % 2)	ans ^= w[i];
		if(!sum){
			int tem = ans;
			for(int i = 1; i <= n; i++)
				ans = max(ans, tem ^ w[i]);
		}	
		printf("%d\n", ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值