The Best Path
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 924 Accepted Submission(s): 383
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 .
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
解法:每条边经过一次,先考虑是欧拉回路或欧拉路径,达成这个条件要求图一定是连通图,欧拉回路每个点的度数是偶数,欧拉路径要求有且只有2个点度数是奇数,其他点度数都为偶数。
针对欧拉路径的情况,因为起点终点已经固定是度数为奇数的点,画一下可以发现每个点经过的次数就是每个点度数除2向上取整(du[i]+1)/2。因为是异或,异或2次相当于没有经过,所以只要留下经过次数是奇数次的点,用一个ans记录下来就好了。
欧拉回路的话,随便画个环也能发现,除了起点,每个点经过的次数都是度数/2次(因为度数都是偶数,除2向上取整不改变,所以可以借用欧拉路径的ans),起点要多经过一次。然后枚举一下起点就可以了。
至于连通性,瞎dfs一下就好了。
CODE
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
struct node{
int v,next;
}E[N*30];
int n,m,top;
int du[N]; ///每个点的度数
int num[N]; ///每个点的价值
int head[N]; ///邻接表头结点
bool vis[N]; ///dfs判断连通性用
void Init()
{
top = 0;
for(int i = 0;i <= n;i++){
du[i] = num[i] = 0;
head[i] = -1;
vis[i] = false;
}
}
void add(int u,int v)
{
E[top].v = v;
E[top].next = head[u];
head[u] = top++;
}
void dfs(int u)
{
vis[u] = true;
for(int i = head[u];i != -1;i = E[i].next){
int v = E[i].v;
if(vis[v]) continue;
dfs(v);
}
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
Init();
for(int i = 1;i <= n;i++)
scanf("%d",&num[i]);
for(int i = 1;i <= m;i++){
int u,v;
scanf("%d%d",&u,&v);
du[u]++;
du[v]++;
add(u,v);
add(v,u);
}
dfs(1); ///判断连通性
bool flag = false;
for(int i = 1;i <= n;i++){
if(!vis[i]) flag = true;
}
if(flag){
printf("Impossible\n");
continue;
}
int cnt = 0;
for(int i = 1;i <= n;i++){
if(du[i]%2 == 1) cnt++;
}
if(cnt > 2){ ///度数为奇数的点个数大于2个,不存在欧拉回路和欧拉路径
printf("Impossible\n");
continue;
}
int ans = 0;
for(int i = 1;i <= n;i++){ ///欧拉路径的情况
du[i] = (du[i]+1)/2;
if(du[i]%2 == 1)
ans ^= num[i];
}
if(cnt == 0){ ///欧拉回路的话枚举下起点取最大值
int tmp = ans;
for(int i = 1;i <= n;i++){
int t = tmp^num[i];
ans = max(ans,t);
}
}
printf("%d\n",ans);
}
return 0;
}