您的位置:首页 > 其它

POJ1386 Play on Words 欧拉路径

2015-08-19 08:56 197 查看
题目链接:http://poj.org/problem?id=1386

题目大意:给你n个单词,判断把这些单词是否能全部连接起来。(当一个单词的首字母等于上个单词的尾字母时两个单词才能连接)。

分析:对于每一个单词,我们只需要纪录下它的首字母和尾字母即可,然后单词接龙就变为了我们熟知的欧拉路径问题了。一个有向图存在欧拉路径,当且仅当该图是连通的,且所有顶点的度数之和为0,或仅存在一个度数为1的顶点和一个度数为-1的顶点,其他顶点的度数为0。

实现代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int ind[30];
bool vis[30];
int par[30],ran[30];
void init()
{
for(int i=0;i<30;i++)
{
par[i]=i;
ran[i]=1;
}
}
int Find(int x)
{
if(par[x]!=x) return par[x]=Find(par[x]);
return x;
}
void Union(int a,int b)
{
int x=Find(a);
int y=Find(b);
if(x==y) return ;
if(ran[x]>ran[y])
{
par[y]=x;
ran[x]+=ran[y];
}
else
{
par[x]=y;
ran[y]+=ran[x];
}
}
int main()
{
int t,n;
char str[1010];
cin>>t;
while(t--)
{
init();
memset(ind,0,sizeof(ind));
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",str);
int len=strlen(str);
int u=str[0]-'a';
int v=str[len-1]-'a';
ind[u]--,ind[v]++;
vis[u]=1,vis[v]=1;
Union(u,v);
}
int sum_par=0;
for(int i=0;i<30;i++)
if(vis[i]&&par[i]==i) sum_par++;
if(sum_par>1)
{
puts("The door cannot be opened.");
continue;
}
int zheng=0,fu=0,ling=0;
for(int i=0;i<30;i++)
{
if(ind[i]==0) ling++;
else if(ind[i]==1) zheng++;
else if(ind[i]==-1) fu++;
}
if(ling==30||(zheng==1&&fu==1&&ling==28))
puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: