poj 1386 Play on Words 有向图欧拉路径判断

题意:

给n个单词,问是否可以将他们排成一排,使得前一个单词的末字符和后一个单词的首字符相同。

分析:

把每个单词看成一条边,转化为有向图是否存在欧拉路径问题。

代码:

//poj 1386
//sep9
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int maxN=30;
int f[maxN];
int in[maxN],out[maxN];
char name[1024];
int find(int u)
{
	return f[u]==u?u:f[u]=find(f[u]);
}
bool solve()
{
	int i,j,origin=-1,end=-1,start=-1;
	for(i=0;i<26;++i)
		if(in[i]>0||out[i]>0){
			if(origin==-1)
				origin=i;
			if(find(i)!=find(origin))
				return false;
			if(in[i]==out[i])
				continue;
			if(in[i]==out[i]+1&&end==-1){
				end=i;
				continue;
			}
			if(in[i]+1==out[i]&&start==-1){
				start=i;
				continue;
			}
			return false;
		}
	if(start==-1&&end==-1)
		return true;
	else if(start!=-1&&end!=-1)
		return true;
	else
		return false;
}

int main()
{
	int i,j,x,y,z,cases,n;
	scanf("%d",&cases);
	while(cases--){
		scanf("%d",&n);
		memset(out,0,sizeof(out));
		memset(in,0,sizeof(in));
		for(i=0;i<26;++i)
			f[i]=i;
		for(i=1;i<=n;++i){
			scanf("%s",name);
			int len=strlen(name);
			int x=name[0]-'a';
			int y=name[len-1]-'a';
			int px=find(x);
			int py=find(y);
			if(px!=py)
				f[px]=py;
			++out[x];
			++in[y];
		}
		if(solve()==false)
			printf("The door cannot be opened.\n");
		else
			printf("Ordering is possible.\n");
	}
	return 0;
}
时间: 2024-11-03 01:41:56

poj 1386 Play on Words 有向图欧拉路径判断的相关文章

poj 1386 Play on Words(有向图欧拉回路)

1 /* 2 题意:单词拼接,前一个单词的末尾字母和后一个单词的开头字母相同 3 思路:将一个单词的开头和末尾单词分别做两个点并建一条有向边!然后判断是否存在欧拉回路或者欧拉路 4 5 再次强调有向图欧拉路或欧拉回路的判定方法: 6 (1)有向图G为欧拉图(存在欧拉回路),当且仅当G的基图连通,且所有顶点的入度等于出度. 7 (2)有向图G为半欧拉图(存在欧拉道路),当且仅当G的基图连通,且存在顶点u的入度比出度大1.v的入度比出度小1, 8 其它所有顶点的入度等于出度(顶点u,v的个数必须都是

POJ 1386 Play on Words(欧拉图的判断)

Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11838   Accepted: 4048 Description Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because ther

poj 1386 欧拉路径

1 /* 2 题意:给出N个单词,一个单词的头字母和另一个单词的尾字母相同则可以相连,问这N个单词是否能完全相连成一行 3 4 题解:求欧拉路径 5 首先以每个单词的首字母和尾字母为点并且连边,然后用DFS求该图是否连通,然后根据点的入度和出度判断是否存在 6 欧拉路径或者欧拉回路(存在回路也是符合要求的) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 11 int map[30][30]; 12 int in[30],out[3

poj 2337 之 有向图 欧拉路径输出

/* poj 2337 之 有向图 欧拉路径输出  每个单词看作一条有向边,顶点即为单词首尾字母,然后求欧拉路径即可. 1)为保证字典序,先对单词按字典序排序 2)深搜,输出单词序列 */ 1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cstddef>

POJ 1386 Play on Words

欧拉回路问题. 题意是说给你一些字符串,类似于成语接龙,上一个字符串尾字母必须和下一个字符串首字母相同. 把所有字符串连成一串. 根据定理判断欧拉通路,然后DFS判连通(并查集也可) 没注意题意 字符串开了str[100] 结果RE.结果字符串最长有1000.改了就AC了. #include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm>

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

题目链接 题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同.给你一组单词问能不能排成上述形式. 思路 :把每个单词看成有首字母指向尾字母的有向边,每个字母看成一个点,题中要求等效于判断图中是否存在一条路径经过每一条一次且仅一次,就是有向欧拉通路.统计个顶点的出入度,如果每个点的出入度都相同,那就是欧拉回路,如果有两个奇数度,那就是欧拉通路,除此之外,都不能满足要求.还有别忘了判断是否连通,此时用到并查集,图中所有的边

poj 1659 Frogs&#39; Neighborhood (Havel-Hakimi定理,判断序列是否可图)

链接:poj 1659 中文题不必解释题意... 其实质是给定一个度序列,判断是否可图, 若可图,输出YES,并输出各顶点之间的连边的情况 否则,输出NO 思路:判断一个序列是否可图,直接利用Havel-Hakimi定理即可 判断任意一个序列是否可图的具体过程: (1)先将序列由大到小排序 (2)设最大的度数为 t ,将最大项删除,然后把最大度数后 (不包括自己)的 t 个度数分别减1(意思就是把度数最大的点与后几个点连边) (3)重复上述两步,如果最大度数t超过了剩下顶点的个数, 或者序列中出

POJ 1659 Frogs&#39; Neighborhood 可图性判断-Havel定理

Description 未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N).如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居.现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系. Input 第一行是测试数据的组数T(0 ≤ T ≤ 20).每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N

POJ 1745 线性和差取余判断

POJ 1745 线性和差取余判断 题目大意:每个数都必须取到,相加或相减去,问所有的方案最后的得数中有没有一个方案可以整除k 这个题目的难点在于dp数组的安排上面 其实也就是手动模仿了一下 比如 一个数,不用说,第一个数之前不用加符号就是本身,那么本身直接对K取余, 那么取17的时候有个余数为2----基础然后来了一个5,(2 + 5)对7取余为0----层层延伸 (2 - 5)对7取余为4(将取余的负数变正) 那么前2个数有余数0和4再来一个-21(0+21)对7取余为0(0-21)对7取余