题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5883
题意: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; }
时间: 2024-12-12 23:42:26