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 P0→P1→…→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 (N≤100000) and M (M≤500000), as described above. The i-th line of the next N lines contains an integer ai(∀i,0≤ai≤10000) 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
题意:
给定无向图,每个节点都有权值,求欧拉路(或欧拉回路),
使得路径上经过节点的权值异或和最大,输出这个最大值。
分析:
欧拉路每个节点经过的次数为 该点的度/2
起点和终点多走一次 (回路则起点多走一次)
根据异或的性质,偶数次的异或值为0,因此只有经过次数为奇数次才对答案有贡献
我们先统计每个点的度
1 .如果所有点的度数都为偶数,则为欧拉回路,
先把所有点的 异或值计算起来 (经过奇数次的点才有贡献)
因为起点多走一次,我们枚举起点,再把前面求出来的数值异或上起点,找到最大值就行了。
2 .如果只有两个点的度数为奇数,则为欧拉路
和前面一样要把所有点的 值异或起来 (经过奇数次的点才有贡献),
因为起点和终点多走一次,所以我们遇到 度为奇数的点,经过次数加1 之后再判断是否对答案有贡献
最后输出即可
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=1e5+5;
int d[maxm];
int p[maxm];
int n,m;
void init(){
memset(d,0,sizeof d);
}
void input(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&p[i]);
}
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
d[a]++;
d[b]++;
}
}
void solve(){
int odd=0;
for(int i=1;i<=n;i++){
if(d[i]%2)odd++;
}
if(odd!=0&&odd!=2){
//如果没有欧拉路
puts("Impossible");
return ;
}
//否则有欧拉路
int ans=0;
for(int i=1;i<=n;i++){
//每个点的访问次数为d/2
int t=d[i]/2;
if(d[i]%2){
//奇数度的点是起点或者终点,访问次数多一次
t++;
}
if(t%2)ans^=p[i];//奇数次的点才有贡献
}
if(odd==2){
//不是回路的情况直接输出答案
printf("%d\n",ans);
return ;
}
//否则是回路的情况,枚举起点
int temp=ans;;
for(int i=1;i<=n;i++){
//起点多走一次
ans=max(ans,temp^p[i]);
}
printf("%d\n",ans);
}
int main(){
// ios::sync_with_stdio(0);
int T;
scanf("%d",&T);
while(T--){
init();
input();
solve();
}
return 0;
}
今天的文章hdu5883 The Best Path (异或和最大的欧拉路)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84076.html