程序员人生 网站导航

HDU-5883-The Best Path【2016青岛】【欧拉路】

栏目:php教程时间:2016-10-08 15:45:04

5883-The Best Path


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

题目链接:HDU⑸883

题目大意: n 个点 m 条无向边的图,找1个欧拉通路/回路使得这个路径所有结点的异或值最大

题目思路:根据欧拉路的性质,

在无向图中,
    欧拉通路:两个点度数为奇数,其余点度数为偶数
    欧拉回路:所有点度数为偶数

所以分为两种情况讨论:

1.欧拉回路
出发点也是终点,所以要遍历哪一个点为出发点(由于出发点多亦或1次,出发点不同结果不同)

2.欧拉通路
两个奇数的点已知,肯定为出发点和终点。

注意:
1. 由于要经过的是每条河而不是每一个湖,所以,只需要判断有河经过的湖是不是联通。
2. 存在河u - > v(u == v) 这些点也要处理,由于可能存在这些点是孤立的,但是也要经过。这里wa了好久

以下是代码:

#include <iostream> #include <iomanip> #include <fstream> #include <sstream> #include <cmath> #include <cstdio> #include <cstring> #include <cctype> #include <algorithm> #include <functional> #include <numeric> #include <string> #include <set> #include <map> #include <stack> #include <vector> #include <queue> #include <deque> #include <list> using namespace std; #define LL long long int a[100005]; int d[100005]; int cc[100005]; #define MAXN 100005 int fa[MAXN] = {0}; int ranks[MAXN] = {0}; void initialise(int n) //初始化 { for (int i = 1; i <= n; i++) fa[i] = i,ranks[i] = 1; } int getfather(int v) //父节点 { return (fa[v] == v) ? v : fa[v] = getfather(fa[v]); } void merge(int x,int y) //合并 { x = getfather(x); y = getfather(y); if (x != y) fa[x] = y,ranks[y] += ranks[x]; } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(d,0,sizeof(d)); memset(cc,0,sizeof(cc)); for (int i = 1; i <= n; i++) { scanf("%d",&a[i]); } initialise(n); for (int i = 0; i < m; i++) { int u,v; scanf("%d%d",&u,&v); cc[u] = 1; cc[v] = 1; d[u]++; d[v]++; merge(u,v); } int cnt = 0; for (int i = 1; i <= n; i++) { if (fa[i] == i && cc[i]) { cnt++; } } if (cnt != 1) { printf("Impossible\n"); continue; } cnt = 0; long long ans = 0; for (int i = 1; i <= n; i++) { if (d[i] % 2 == 0) { int kk = d[i] / 2; if(kk % 2) { ans ^= a[i]; } } else { if (((d[i] + 1) / 2) % 2) ans ^= a[i]; cnt++; } } if(cnt == 0) { ans = ans ^ a[1]; for (int i = 2; i <= n; i++) { ans = max(ans ^ a[i],ans); } } if (cnt == 0 || cnt == 2)printf("%lld\n",ans); else printf("Impossible\n"); } return 0; }
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐