hdu 1116 Play on Words(欧拉图)

来源:互联网 发布:根据域名查询服务器 编辑:程序博客网 时间:2024/05/21 19:22

1.题意:给n个单词,问是否能按成语接龙的方式将所有的单词串连起来。

2.思路:把单词看成是从首字母到尾字母的有向边(弧)即可。只要该有向图是欧拉图,那么就可以连。否则不可以。写并查集中的Union的时候要注意是a=Find(a);不要再重复犯错了

3.代码:

#include<cstdio>#include<cstring>using namespace std;int father[30];char s[1005];int in[30],out[30];int vis[30];int deta[30];int mat[30][30];int f(int a){    return a>0?a:-a;}int Find(int a){    int r=a;    while(father[a]!=a)    {        a=father[a];    }    father[r]=a;    return a;}void Union(int a,int b){    a=Find(a);    b=Find(b);    if(a!=b)    {        father[b]=a;    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        memset(mat,0,sizeof(mat));        scanf("%d",&n);        for(int i=1; i<=26; i++)        {            father[i]=i;            in[i]=out[i]=0;            vis[i]=0;        }        for(int i=1; i<=n; i++)        {            scanf("%s",s);            int len=strlen(s);            int a,b;            a=s[0]-'a'+1;            b=s[len-1]-'a'+1;            in[a]++;            out[b]++;            vis[a]=vis[b]=1;            if(mat[a][b]==0&&mat[b][a]==0)            {                Union(a,b);                mat[a][b]=mat[b][a]=1;            }        }        int cnt=0;        int cnt1=0;        for(int i=1; i<=26; i++)        {            if(Find(i)==i&&vis[i]==1)                cnt++;            if(vis[i]==1&&in[i]!=out[i])            {                cnt1++;                deta[cnt1]=in[i]-out[i];            }        }        if(cnt==1&&(cnt1==0||(cnt1==2&&f(deta[1])==1&&f(deta[2])==1)))        {            printf("Ordering is possible.\n");        }        else            printf("The door cannot be opened.\n");    }    return 0;}

0 0
原创粉丝点击