uva10129play on words(歐拉回路)
阿新 • • 發佈:2018-12-09
看了以前的提示才寫出來的,判斷連通用了dfs(並查集是什麼?)
對於歐拉回路:
首先判斷:是否存在一條路徑,使得我能不重複地走過所有邊?
1、首先,圖中所有點是連通的 (dfs,並查集)
2、(1)無向圖:除了起點和終點,其他點的進出次數必須相等。
(2)最多有兩個點的入度不等於出度,而且必須是其中一個點的出度比入度恰好大1(起點),另一個的入度比出度大1(終點)。
第一點往往在第二點後判斷,在判斷第二點時找到歐拉回路的起點,用dfs從起點開始走出歐拉回路(但為什麼從起點開始走出來的線路就是歐拉回路?),如果有點沒有被訪問到,說明圖不連通。
#include<stdio.h> #include<string.h> const int max_input = 1000 + 10; const int maxn = 30; char input[max_input]; int graph[maxn][maxn]; int in[maxn]; int out[maxn]; int set[maxn]; // int visited[maxn]; // void dfs(int u) { for(int v = 0; v < maxn; ++v) { if(graph[u][v] > 0) { --graph[u][v]; dfs(v); visited[v] = 1; } } } int main() { // freopen("input.txt", "r", stdin); int T, N; scanf("%d", &T); for(int k = 0; k < T; ++k) { scanf("%d", &N); memset(graph, 0, sizeof(graph)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); memset(set, 0, sizeof(set)); //which of the 'a' to 'z' is in the graph int min = 30; for(int i = 0; i < N; ++i) { scanf("%s", input); int n1, n2; n1 = input[0] - 'a', n2 = input[strlen(input)-1] - 'a'; graph[n1][n2]++; out[n1]++, in[n2]++; set[n1] = set[n2] = 1; min = n1 < min? n1: min; min = n2 < min? n2: min; } bool ok = true; int cnt1 = 0, cnt2 = 0; int rcs_start = min; for(int i = 0; i < maxn; ++i) { if(in[i] == out[i]) continue; else if(out[i] == in[i]+1) { cnt1++; rcs_start = i; } else if(in[i] == out[i]+1) cnt2++; else { ok = false; break; } } if(!((cnt1 == 0 && cnt2 ==0) || (cnt1==1 && cnt2 ==1))) ok = false; //connected? memset(visited, 0, sizeof(visited)); visited[rcs_start] = 1; dfs(rcs_start); for(int i = 0; i < maxn; ++i) { if(set[i] && !visited[i]) { ok = false; break; } } if(ok) puts("Ordering is possible."); else puts("The door cannot be opened."); } }