您的位置:首页 > 其它

hdu 1116 Play on Words

2011-08-03 09:27 483 查看
我的思路:

用俩个数组分别记录出现过的节点的入度和出度,这样只有一个字母的入度比出度大1,一个字母的出度比入度大1,或者是所有有字母的出度和入度都一样,他就是欧拉路

但这样还差了一个联通性的判断 于是我用了一个辅助数组 f[] 用并查集的方式判断是否连通

代码:

#include<iostream>
#include<string>
using namespace std;
int f[30],c[30],r[30];
char s[1005];
int find(int x)
{
if(x==f[x])
return f[x];
f[x]=find(f[x]);
return f[x];
}
void Union(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b)
return ;
f[a]=b;
return ;
}

void init()
{
for(int i=0;i<26;i++)
f[i]=i;
memset(c,0,sizeof(c));
memset(r,0,sizeof(r));
}
int main()
{
int i,j,cas,n;
cin>>cas;
while(cas--)
{
init();
cin>>n;
for(i=0;i<n;i++)
{
cin>>s;
int a=s[0]-'a';
int b=s[strlen(s)-1]-'a';
Union(a,b);
r[b]++;
c[a]++;//累加 节点的入度和出度
}
int count=0;
for(i=0;i<26;i++)//计算根节点数目
{
if(i==find(i)&&(r[i]||c[i]))
count++;
}
if(count!=1)//判断是否连通
{
cout<<"The door cannot be opened."<<endl;
continue;
}
int p1=0,p2=0;
for(i=0;i<26;i++)
{
if(c[i]>r[i])
p1+=c[i]-r[i];
if(r[i]>c[i])
p2+=r[i]-c[i];
}
if((p1==0&&p2==0)||(p1==1&&p2==1))
cout<<"Ordering is possible."<<endl;
else
cout<<"The door cannot be opened."<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: