您的位置:首页 > 其它

POJ 1386 Play on Words(欧拉路)

2017-07-17 21:45 483 查看
http://poj.org/problem?id=1386

题意:

给出多个单词,只有单词首字母与上一个单子的末尾字母相同时可以连接,判断所有字母是否可以全部连接在一起。

思路:

判断是否存在欧拉道路,每个单词只需要处理首字母和尾字母就可以了。

还有需要注意的就是需要判断图是否连通,我在这里用了并查集来判断。

有向图D存在欧拉道路的充要条件是:D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 1000 + 5;

int n;
int in[30],out[30];
int g[30][30];
int p[30];
char str[maxn];

int Find(int x)
{
return x==p[x]?x:p[x]=Find(p[x]);
}

int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(g,0,sizeof(g));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));

for(int i=0;i<26;i++)  p[i]=i;
scanf("%d",&n);
getchar();
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';
g[u][v]=1;
out[u]++;
in[v]++;

int x=Find(u);
int y=Find(v);
if(x!=y)  p[x]=y;
}

int cnt=0;
for(int i=0;i<26;i++)
{
if((in[i]||out[i]) && p[i]==i)
cnt++;
}
if(cnt>1)
{
puts("The door cannot be opened.");
}
else
{
int num1=0,num2=0, num3=0;
for(int i=0;i<26;i++)
{
if(in[i]!=out[i])
{
if(in[i]-out[i]==1)  num1++;
else if(in[i]-out[i]==-1)  num2++;
else num3++;
}
}
if(num3==0 && ((num1==0 && num2==0)||(num1==1 && num2==1)))
puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: