uva10129play on words(欧拉回路)

看了以前的提示才写出来的,判断连通用了dfs(并查集是什么?)

对于欧拉回路:

首先判断:是否存在一条路径,使得我从一个结点出发, 每条边恰好走过一次(or给定的次数)

1、首先,图中所有点是连通的 (dfs,并查集)

2、奇点

(1)无向图:除了起点和终点,其他点的进出次数必须相等。

(2)最多有两个点的入度不等于出度,而且必须是其中一个点的出度比入度恰好大1(起点),另一个的入度比出度大1(终点)。

第一点往往在第二点后判断,在判断第二点时找到欧拉回路的起点,用dfs从起点开始走出欧拉回路(但为什么从起点开始走出来的线路就是欧拉回路?),如果有点没有被访问到,说明图不连通。

 

其实不需要用set记录那些结点是不是在图里面的,由于每条边必须走过给定的次数,所以如果dfs后有graph[u][v]不为0,就不行了

#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.");
	}
}

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯智能台灯

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值