hdu 1116 Play on Words

来源:互联网 发布:老大哥在看着你 知乎 编辑:程序博客网 时间:2024/06/10 10:47

用深搜超时。
后来用欧拉回路。
union set 原来是并查集 ,是种数据结构,我看英文知道有这个union set 刚开始还以为是种算法。

union set code:

int height[MAX];int root[MAX];for(int i=0;i<26;i++){       root[i]=i;       height[i]=1;   }int Find(int a){    if(root[a]!=a){        root[a]=Find(root[a]);    }    return root[a];}void un(int a ,int b){    int x,y;    x=Find(a);    y=Find(b);    if(x!=y){        if(height[x]<height[y]){        root[y]=x;        height[x]++;        }else{         root[x]=y;        height[y]++;        }    }}

AC 代码,用高度进行了修正,比较x,y两个根。把数量多的根,附在数量少的根上。就是说哪个根的数量比较少,哪个就是最后的根。
加上这个前是1230ms ,加上后957ms。

AC代码

#include <iostream>#include<cstring>#include<cstdio>#include<string>#include<queue>using namespace std;const int MAX=30;int n;int root[MAX];int visited[MAX];int in[MAX];int out[MAX];int p[MAX];int height[MAX];int Find(int a){    if(root[a]!=a){        root[a]=Find(root[a]);    }    return root[a];}void un(int a ,int b){    int x,y;    x=Find(a);    y=Find(b);    if(x!=y){        if(height[x]<height[y]){        root[y]=x;        height[x]++;        }else{         root[x]=y;        height[y]++;        }    }}int main(){   int t;   scanf("%d",&t);   while(t--){        scanf("%d",&n);        memset(visited,false,sizeof(visited));        memset(in,0,sizeof(in));        memset(out,0,sizeof(out));        // init root        for(int i=0;i<26;i++){            root[i]=i;            height[i]=1;        }        string tmp;        int a,b;        for(int i=0;i<n;i++){           cin>>tmp;           int len=tmp.length();           a=tmp[0]-'a';           b=tmp[len-1]-'a';          //            un(a,b);           visited[a]=true;           visited[b]=true;           out[a]++;           in[b]++;        }        //        for(int i=0;i<26;i++){            root[i]=Find(i);        }        int cnt=0;        for(int i=0;i<26;i++){            if(visited[i]&&root[i]==i)cnt++;        }        if(cnt>1){            printf("The door cannot be opened.\n");            continue;        }        int j=0;        for(int i=0;i<26;i++){            if(visited[i]&&out[i]!=in[i]){                p[j++]=i;            }        }        if(j==0){            printf("Ordering is possible.\n");            continue;        }        if(j==2&&((out[p[0]]-in[p[0]]==1&&in[p[1]]-out[p[1]]==1)||(out[p[1]]-in[p[1]]==1&&in[p[0]]-out[p[0]]==1))){             printf("Ordering is possible.\n");             continue;        }         printf("The door cannot be opened.\n");   }    return 0;}