【hdu5883】【欧拉路】 每个点都有权值,要求按照欧拉路或者通路走一遍是的使得权值异或值最大

传送门:HDU 5883 The Best Path

描述:

The Best Path

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 807    Accepted Submission(s): 337


Problem Description
Alice is planning her travel route in a beautiful valley. In this valley, there are  N  lakes, and  M  rivers linking these lakes. Alice wants to start her trip from one lake, and enjoys the landscape by boat. That means she need to set up a path which go through every river exactly once. In addition, Alice has a specific number ( a1,a2,...,an ) for each lake. If the path she finds is  P0P1...Pt , the lucky number of this trip would be  aP0XORaP1XOR...XORaPt . She want to make this number as large as possible. Can you help her?
 

Input
The first line of input contains an integer  t , the number of test cases.  t  test cases follow.

For each test case, in the first line there are two positive integers  N (N100000)  and  M (M500000) , as described above. The  i -th line of the next  N  lines contains an integer  ai(i,0ai10000)  representing the number of the  i -th lake.

The  i -th line of the next  M  lines contains two integers  ui  and  vi  representing the  i -th river between the  ui -th lake and  vi -th lake. It is possible that  ui=vi .
 

Output
For each test cases, output the largest lucky number. If it dose not have any path, output "Impossible".
 

Sample Input
  
  
2 3 2 3 4 5 1 2 2 3 4 3 1 2 3 4 1 2 2 3 2 4
 

Sample Output
  
  
2 Impossible
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:   5899  5897  5896  5893  5892 


思路:

节点 i 的贡献为((d[i] / 2) % 2)* a[i]

欧拉回路的起点贡献多一次,欧拉通路起点和终点也多一次。

回路要枚举起点的情况

根本不需要考虑怎么走的

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,m;
int a[maxn],d[maxn];

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
			int cnt=0,flag=0;
			scanf("%d%d",&n,&m);
			memset(d, 0, sizeof(d));
			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);
				d[u]++;d[v]++;
			}
			for(int i=1; i<=n; i++){
				if(d[i]&1)cnt++;
			}
			if(cnt==0 || cnt==2)flag=1;
			if(!flag){ puts("Impossible"); continue;}
			int ans=0;
			for(int i=1; i<=n; i++){
				if(((d[i]+1)/2)%2)ans^=a[i];
			}
			int mx=0;
			if(!cnt){//是欧拉回路的时候要另外枚举起点,起点贡献+1
				for(int i=1; i<=n; i++)
					mx=max(ans^a[i], mx);
				ans=mx;
			}
			printf("%d\n",ans);
			
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值