hdu 1116 Play on Words

我的思路:

用俩个数组分别记录出现过的节点的入度和出度,这样只有一个字母的入度比出度大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;
}
posted @ 2011-08-03 09:27  枕边梦  阅读(192)  评论(0编辑  收藏  举报