题意: T组数据,n个湖(即点),m条河(即边),并且每个点都有一个权值。如果这个图能构成欧拉路(包括回路),求从起点异或到终点的值中的最大值。
题解:
- 连通性。 由于题目性质,这道题中的点都是相互连通的,不需要另外判断。
- 欧拉路(回路)。 判断所有点的度数即可:欧拉回路——所有点都是偶点,欧拉路——只有两个奇点,其他全为偶点。
- 异或结果。 实际上没到一个点都要求一遍异或,那为什么可以求最大值呢?而且欧拉回路中虽然边不重复,但是点会重复,那么我们一个点需要求几次异或呢?
- (deg[i] + 1) / 2 % 2。 试想,如果到达某个点偶数次,某个权值需要异或偶数次,a ^ a = 0,就变得没有意义了。所有我们只需要找到经过奇数次的点,但请注意是 (deg[i] + 1) / 2 % 2 而不是deg[i] % 2 。为什么?在欧拉路中,起点和终点的度数一定是奇数,例如1,那么经过次数为1;途中的点的度数一定为偶数,例如2,那么经过次数为1。所以我们要求的是某个个点的经过次数,而不是度数本身。而经过次数与度数的关系即为:
次数 = (deg[i] + 1) / 2
- 最大值。 那既然每经过一个点都要异或一次,何来最大值呢?欧拉回路。 如果图是欧拉回路的话,我们可以将图中原本一个经过偶数次的点作为起点,思考一下成为起点之后它还是经过偶数次吗?因为有可能可以改变某个点的经过次数,而经过次数决定了这个权值的异或是否有意义,从而影响了最后的结果。
- (deg[i] + 1) / 2 % 2。 试想,如果到达某个点偶数次,某个权值需要异或偶数次,a ^ a = 0,就变得没有意义了。所有我们只需要找到经过奇数次的点,但请注意是 (deg[i] + 1) / 2 % 2 而不是deg[i] % 2 。为什么?在欧拉路中,起点和终点的度数一定是奇数,例如1,那么经过次数为1;途中的点的度数一定为偶数,例如2,那么经过次数为1。所以我们要求的是某个个点的经过次数,而不是度数本身。而经过次数与度数的关系即为:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int T, n, m, a, b;
int w[N], deg[N];
int main(){
scanf("%d", &T);while(T--){
scanf("%d%d", &n, &m);
memset(deg, 0, sizeof deg);
for(int i = 1; i <= n; i++) scanf("%d", w + i);
while(m--){
scanf("%d%d", &a, &b);
deg[a]++, deg[b]++;
}
int sum = 0, ans = 0;
for(int i = 1; i <= n; i++) if(deg[i] % 2) sum++;
if(sum != 0 && sum != 2){ printf("Impossible\n"); continue;}
for(int i = 1; i <= n; i++) if((deg[i] + 1) / 2 % 2) ans ^= w[i];
if(!sum){
int tem = ans;
for(int i = 1; i <= n; i++)
ans = max(ans, tem ^ w[i]);
}
printf("%d\n", ans);
}
return 0;
}