hdu 1116 Play on Words

并查集+有向欧拉回路 有向欧拉通路的判定。

并查集用来判断是不是连通图。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn=100010;
int sumru[maxn],sumchu[maxn],father[30],flag[30],ff[30];
char s[1000];

int findd(int x)
{
    if(x!=father[x]) father[x]=findd(father[x]);
    return father[x];
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,i;
       
        scanf("%d",&n);
        memset(sumru,0,sizeof(sumru));
        memset(sumchu,0,sizeof(sumchu));
        memset(flag,0,sizeof(flag));
        memset(ff,0,sizeof(ff));
        for(i=0;i<=25;i++) father[i]=i;

        for(i=0;i<n;i++)
        {
            scanf("%s",s);
            sumru[s[strlen(s)-1]-'a']++;
            sumchu[s[0]-'a']++;
            int ft=findd(s[0]-'a');
            int fw=findd(s[strlen(s)-1]-'a');
            if(ft!=fw) father[ft]=fw;
            flag[s[strlen(s)-1]-'a']=1;
            flag[s[0]-'a']=1;
        }

        int jieguo=1,tott=0;
        int uu[maxn];

        for(i=0;i<=25;i++) if(flag[i]==1) ff[findd(i)]=1;
        for(i=0;i<=25;i++) if(ff[i]==1) tott++;
        if(tott!=1)jieguo=0; 
        tott=0;
        if(jieguo==1)
        {
            for(i=0;i<=25;i++)
            {
                if(sumru[i]==0&&sumchu[i]==0) continue;//这个点没有出现
                if(sumru[i]==sumchu[i]) continue;
                if(sumru[i]!=sumchu[i])
                {
                    uu[tott]=i;
                    tott++;
                }
            }
            if(tott!=2&&tott!=0) jieguo=0;
            if(tott==2)
            {
                if((sumru[uu[0]]-sumchu[uu[0]]==1&&sumru[uu[1]]-sumchu[uu[1]]==-1)||(sumru[uu[0]]-sumchu[uu[0]]==-1&&sumru[uu[1]]-sumchu[uu[1]]==1)) jieguo=jieguo;
                else jieguo=0;
            }
        }
        
        if(jieguo==0) printf("The door cannot be opened.\n");
        else printf("Ordering is possible.\n");
    }
    return 0;
}

 

posted @ 2015-06-12 21:48  Fighting_Heart  阅读(300)  评论(0编辑  收藏  举报