1. 程式人生 > >uva10129play on words(歐拉回路)

uva10129play on words(歐拉回路)

看了以前的提示才寫出來的,判斷連通用了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.");
	}
}