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 aP0 XOR aP1 XOR … XOR aPt. She want to make this number as large as possible. Can you help her?
参考题解
先判断图是否只有一个连通块,然后判断是否存在欧拉回路或者路径,欧拉路径每个点经过 (度数+1)/2 次,欧拉回路也一样,但是起点多走一次,每个点都可以作为起点。
欧拉通路判断条件:奇数度顶点个数最多为2个,当全部都是偶数度顶点时,图中包含欧拉回路。首先按照欧拉通路计算,计算出来的值是一定要走过的所有边构成的价值,如果存在欧拉回路,就枚举每一个顶点,因为刚刚是按照通路算的,现在遍历异或返回起点的价值。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5+5;
int degree[maxn], value[maxn], f[maxn];
int getf(int x)
{
return x == f[x] ? x : f[x] = getf(f[x]);
}
inline void join(int a, int b)
{
int x = getf(a);
int y = getf(b);
if(x != y) f[x] = y;
}
int main()
{
int T, n, m;
cin >> T;
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
{
degree[i] = 0;
f[i] = i;
scanf("%d", &value[i]);
}
for(int i = 1; i <= m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
degree[u]++, degree[v]++;
join(u, v);
}
int sum = 0, flag = 0;
for(int i = 1; i <= n; i++)
{
if(getf(i) == i) sum++;
if(degree[i]&1) flag++;
}
if(sum > 1 || flag > 2)
{
printf("Impossible\n");
continue ;
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
int temp = (degree[i]+1)>>1;
while(temp--)
ans ^= value[i];
}
if(flag == 0)
{
int temp = ans;
for(int i = 1; i <= n; i++)
{
ans = max(temp^value[i], ans);
}
}
printf("%d\n", ans);
}
return 0;
}