1007 The Best Path(无向图的欧拉路)

来源:互联网 发布:c语言product函数 编辑:程序博客网 时间:2024/06/10 02:37

The Best Path

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 541    Accepted Submission(s): 220


Problem Description
Alice is planning her travel route in a beautiful valley. In this valley, there areN 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 P0P1...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 (N100000) and M (M500000), as described above. The i-th line of the next N lines contains an integer ai(i,0ai10000) 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
23 23451 22 34 312341 22 32 4
 

Sample Output
2Impossible
 

Source

2016 ACM/ICPC Asia Regional Qingdao Online 


这题让我对欧拉路有了深一点的认识。   

欧拉路:分有向图的欧拉路和无向图的欧拉路。前几天做过有向图的欧拉路,这题就是无向图的欧拉路(后面也是针对无向图来讲)。

不管是无向图也好,有向图也罢,欧拉路分为点欧拉和边欧拉。 点欧拉就是每个点只能走一次,边欧拉就是每条边只能走一次。

这题是边欧拉,同时,每个点都要走一次,要你输出走这条欧拉路的最大点权的亦或值

边欧拉,两种情况:1.每个点的度数都是偶数,这时,不论从哪个点出发,都能走出欧拉路,且最后一定会回到出发点,也就是说起点会经历奇数次((度+1)/2)通过,其它点会经历偶数次(度/2)通过  (所以这题如果是这种情况,就只要考虑起点是哪一个就ok,因为同一个点偶数次亦或就是1) 2.有两个点的度是奇数,那么起点必定在这两个点中,无论哪个点都可以作为起点,他们会经历((度+1)/2)次(刚开始在那个点也算经历一次)。


#include <iostream>#include <cstdio>#include <string.h>#include <algorithm>using namespace std;int T, val[100005], du[100005], pre[100005];int find(int x){return pre[x] == x ? x : pre[x] = find(pre[x]);}int main(){    cin >> T;    while(T--){        memset(du, 0, sizeof(du));        int n, m, flag = 0, odd = 0;        cin >> n >> m;        for(int i = 1; i <= n; i++) pre[i] = i;        for(int i = 1; i <= n; i++) scanf("%d", &val[i]);        for(int i = 1; i <= m; i++){            int u, v;            scanf("%d %d", &u, &v);            du[u]++; du[v]++;            int x = find(u), y = find(v);            if(x != y) pre[x] = y;        }        for(int i = 1; i <= n; i++){            if(pre[i] == i) flag++;            if(du[i] % 2 != 0) odd++;        }        if(flag > 1) { printf("Impossible\n"); continue;}        if(odd == 2){            int ans = 0;            for(int i = 1; i <= n; i++){                du[i] = (du[i] + 1) / 2;                if(du[i] & 1)                    ans ^= val[i];            }            printf("%d\n", ans);        }        else if(odd == 0){            int ans = 0;            for(int i = 1; i <= n; i++)                ans = max(ans, ans ^ val[i]);            printf("%d\n", ans);        }        else printf("Impossible\n");    }    return 0;}


0 0
原创粉丝点击