Bryce1010模板
https://vjudge.net/contest/250561#problem/F
题意:
有一个图有N个顶点,M条边,求遍历所有的边,并要求每条边只能走一次,经过的节点的最终异或值。
思路:
回去复习图论基础了
先判断是否含有欧拉路径,如果存在的话有两种情况,有起点和终点不同的欧拉路径,这样我们只需把经过奇数次的点的权值异或起来即可;
还有就是起点和终点相同的欧拉回路;我们在原来的基础上枚举出一个起点,使得结果最大即可;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define met(a, b) memset(a, b, sizeof(a))
#define N 100005
#define INF 0x3f3f3f3f
typedef long long LL;
int du[N], n, a[N];
int Judge()
{
int odd = 0, ans = 0;
for(int i=1; i<=n; i++)
{
if(du[i]&1)
odd++;
}
if(odd !=0 && odd != 2)///度数为奇数的点只有是这两种情况下才存在欧拉路径;
return -1;
for(int i=1; i<=n; i++)
{
du[i] = (du[i]+1)/2;///经过一个点的次数;
if(du[i]&1)///当经过偶数次时异或结果为0,所以只需异或奇数即可;
ans ^= a[i];
}
if(odd == 0)///当度数都为偶数时,说明存在欧拉回路,我们只需枚举起点,保存最大值即可;
{
for(int i=1; i<=n; i++)
ans = max(ans, ans^a[i]);
}
return ans;
}
int main()
{
int T, m;
scanf("%d", &T);
while(T--)
{
met(du, 0);
scanf("%d %d", &n, &m);
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);
du[u] ++; du[v] ++;
}
int ans = Judge();
if(ans == -1) puts("Impossible");
else printf("%d\n", ans);
}
return 0;
}