Uva 10129 (dfs判断连通 +欧拉回路)

传送门!!!!!!!!----->点击打开题目链接

题意:输入一个n代表有n个单词,接下来输入n个单词,问是否可以把所有的单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同。

思路:把字母看成节点,单词看成有向边,建图。当且仅当途中存在欧拉路径时题目叙述成立。

欧拉回路:能否从无向图中的一个节点出发走出一条道路,每条边恰好经过一次,。如果可以,则这样的路线称为欧拉道路。

欧拉道路的定理:最多只能有两个点的度入度和出度不相等,而且必须是其中一个点的出度比入度大1(把他作为起点),另一个的入度比出度大一(作为终点)。并且图是连通的。

所以这道题的思路就是判定建出来的图是否存在欧拉回路。所以需要证明两步,第一步是证明这个图是连通的,第二部是证明最多存在两个点入度和出度的不相等,且一个出度比入度大一,一个入度比出度大一。

详情看代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 30;
int vis[maxn]; //标记数组,用来标记该点是否联通。 
int son,far;
int in[maxn]; // 统计某个点的入度 
int out[maxn]; //统计某个点的出度 
int [maxn][maxn]; // 图 

void dfs(int u){      // 判断是否为连通图  
	vis[u] = 1;
	for(int i = 0 ; i < maxn ; i ++){
		if(G[u][i] && !vis[i])
		dfs(i);
	}
}
int main(){
	string str;
	int kase;
	cin >> kase ;
	while(kase --){
		int n ,cnt = 0,n_in = 0,n_out = 0, start= 0;
		cin >> n;
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		memset(G,0,sizeof(G));
		memset(vis,0,sizeof(vis));
		for(int i = 0 ; i < n ; i ++){ // 建图 
			cin >> str;
			far = str[0] - 'a';
			son = str[str.size() - 1] - 'a' ;
			out[far] ++;
			in[son] ++;
			G[far][son] = 1;
		}
		for(int i = 0 ; i < 27 ; i++){  // 统计点的入度和出度 
			if(in[i] != out[i]){  //当入度和出度不相等时 
				if(in[i] == out[i] + 1)
					n_in ++;
				else if(in[i] + 1 == out[i]) 
					n_out ++,start = i ; 
				else n_in += maxn;
			}
			if(start = 0 && in[i] == out[i])  // 当所有点入度和出度 都相等的时候,任何一个点都可以作为起点。 
				start = i;
		}
		int ok = 0;
		if((n_in == 1 && n_out == 1) || (n_in == 0 && n_out ==0)){  //判断条件2是否成立 
			dfs(start);
			ok = 1;
		}
			
		for(int i = 0 ; i < 27 ; i++) //判断条件1是否成立 当这点存在但是不连通时 cnt++; 
			if(vis[i] == 0 && (in[i]||out[i]))
				cnt ++;
		if(cnt == 0 &&ok == 1)
			cout <<"Ordering is possible." <<endl;
		else 
			cout << "The door cannot be opened." <<endl; 
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值