1. 程式人生 > >有向圖的歐拉回路判定問題 poj1386

有向圖的歐拉回路判定問題 poj1386

這個題也卡卡卡,發現自己好粗心,唉.。

有向圖的判定:

統計每個點的出度和入度,

前提是有向圖是連通圖。
1. 如果每個點的出度 = 入度 則存在歐拉回路。
2. 如果有且僅有兩點出度、入度不想等,且這兩個點的出度 - 入度差為1 或 -1.差為1的那個點是尤拉圖的起點,為 -1 的是重點。

這個題先來判斷圖的連通性,用並查集的方法,值得注意的一點是並查集是以點為元素的,所以要開26長度的陣列。
在接下來就是判斷出度和入度了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string> #include<cmath> using namespace std; const int MAXN = 1e5 + 10; int father[30]; int _rank[30]; int d1[30]; // 出度 int d2[30]; // 入度 bool h[MAXN]; // 判斷是否出現邊中 void init() { for(int i = 1;i <= 26;++i) { father[i] = i; _rank[i] = 0; } return ; } int _find(int
i) { int root = i; int temp = i; while(father[root] != root) { root = father[root]; } while(father[temp] != root) { int t; t = father[temp]; father[temp] = root; temp = t; } return root; } void _union(int x,int y) { int
root1 = _find(x); int root2 = _find(y); if(root1 != root2) { if(_rank[root1] > _rank[root2]) { father[root2] = root1; } else { father[root1] = root2; if(_rank[root1] == _rank[root2]) { _rank[root2]++; } } } return; } struct Edge { int u,v; }; Edge e[MAXN]; int n; bool tell() // 判斷連通性 { init(); for(int i = 1;i <= n;++i) // 先進行一邊合併 { int u = e[i].u; int v = e[i].v; if(_find(u) != _find(v)) { _union(u,v); } } bool flag = 1; int l= -1; for(int i = 1;i <= 26;++i) // 在判斷father陣列是否只有一個父親節點 { if(h[i]) // 將不存在點排除 { if(l == -1) { l = father[i]; } else { if(father[i] != father[l]) { flag = 0; } } } } return flag; } int main() { int T; cin >> T; while(T--) { memset(d1,0,sizeof(d1)); memset(d2,0,sizeof(d2)); memset(h,0,sizeof(h)); cin >> n; string s; for(int i = 1; i <= n;++i) { cin >> s; e[i].u = s[0] - 'a' + 1; e[i].v = s[s.size() - 1] - 'a' + 1; d1[e[i].u]++; d2[e[i].v]++; h[e[i].u] = 1; h[e[i].v] = 1; } bool flag = tell(); int a,b,k = 0,t = 0; if(flag) { for(int i = 1;i <= 26;++i) { if(d1[i] != d2[i]) { t = 1; k++; if(k == 1) { a = i; } if(k == 2) { b = i; } } } if(!t) cout << "Ordering is possible." << endl; else { if(k == 2) { if((int )abs(d1[a] - d2[a]) == 1 && (int )abs(d1[b] - d2[b]) == 1) { cout << "Ordering is possible." << endl; } else { cout << "The door cannot be opened." << endl; } } else { cout << "The door cannot be opened." << endl; } } } else { cout << "The door cannot be opened." << endl; } } return 0; }