1. 程式人生 > >The Best Path HDU

The Best Path HDU

  圖(無向圖或有向圖)中恰好通過所有邊一次且經過所有頂點的的通路成為尤拉通路,圖中恰好通過所有邊一次且經過所有頂點的迴路稱為歐拉回路,具有歐拉回路的圖稱為尤拉圖,具有尤拉通路而無歐拉回路的圖稱為半尤拉圖。

  規定平凡圖(只有一個點)是尤拉圖。

性質與定理:

  1. 無向圖G是尤拉圖當且僅當G是連通的且沒有奇度頂點。
  2. 無向圖G是半尤拉圖當且僅當G是連通的且恰有兩個奇度頂點。
  3. 有向圖D是尤拉圖當且僅當D是強連通的且每個頂點恰有兩個奇度頂點。
  4. 有向圖D是半尤拉圖當且僅當D是單連通的且每個頂點入度等於出度。

顯然,該題為求一條歐拉回路或尤拉通路,並求權值異或最大值,我們知道偶數次異或運算結果為0,通過點的度數,我們不難判斷出該點參與異或運算的次數,度數為n的點在歐拉回路起始位置被運算的次數為(n + 1)/ 2 + 1,其他情況運算次數為(n + 1) / 2

題目:題目連結

AC程式碼:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int maxn = 100000 + 5;
 9 
10 int n, m, ans;
11 int w[maxn], num[maxn];
12 
13 bool solve();
14 
15 int main()
16 {
17 //freopen("in.txt", "r", stdin); 18 ios::sync_with_stdio(0); 19 cin.tie(0); 20 21 int T, u, v; 22 cin >> T; 23 while(T--) { 24 cin >> n >> m; 25 for(int i = 1; i <= n; ++i) { 26 cin >> w[i]; 27 num[i] = 0
; 28 } 29 for(int i = 0; i < m; ++i) { 30 cin >> u >> v; 31 ++num[u]; 32 ++num[v]; 33 } 34 if(solve()) 35 cout << ans << endl; 36 else 37 cout << "Impossible" << endl; 38 } 39 return 0; 40 } 41 42 bool solve() { 43 int sum = 0; 44 for(int i = 1; i <= n; ++i) 45 if(num[i] & 1) 46 ++sum; 47 if(sum != 0 && sum != 2) 48 return false; 49 int temp = 0; 50 for(int i = 1; i <= n; ++i) 51 if((num[i] + 1) >> 1 & 1) 52 temp ^= w[i]; 53 if(sum == 2) 54 ans = temp; 55 else { 56 ans = 0; 57 for(int i = 1; i <= n; ++i) 58 ans = max(ans, temp ^ w[i]); 59 } 60 return true; 61 }