标签:拓扑排序
题意:n个姓名,按照某种“字典序”。
问如果存在这样的字典序,输出字典序‘a‘到‘z’26个字母的顺序。
思路:拓扑排序。对于str[i]和str[i+1]如果在位置k出现不同,那么x=str[i][k]-‘a‘+1,y=str[i+1][k]-‘a‘+1,从x->y连一条边,y的入度in[y]++。
然后拓扑排序,如果形成环,就说明不行,不然依次输出对应字符。(ps:len1为str[i]的长度,len2为str[i+1]的长度,如果len1>len2且前len2个均相同,也说明不行)详见代码:
/********************************************************* file name: codeforces510C.cpp author : kereo create time: 2015年02月03日 星期二 16时03分28秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=100+50; const int MAXN=100000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=100000000+7; #define L(x) (x<<1) #define R(x) (x<<1|1) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n,edge_cnt; char str[N][N]; int head[N],in[N],ans[N],vis[N][N]; struct Edge{ int v,next; }edge[N]; void init(){ edge_cnt=0; memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); } void addedge(int u,int v){ edge[edge_cnt].v=v; edge[edge_cnt].next=head[u]; head[u]=edge_cnt++; } int main(){ while(~scanf("%d",&n)){ init(); for(int i=0;i<n;i++) scanf("%s",str[i]); int flag=1; for(int i=0;i<n-1;i++){ int len1=strlen(str[i]),len2=strlen(str[i+1]); int tag=0; for(int j=0;j<len1 && j<len2;j++){ if(str[i][j]!=str[i+1][j]){ tag=1; int u=str[i][j]-'a'+1,v=str[i+1][j]-'a'+1; if(!vis[u][v]){ vis[u][v]=1; in[v]++; addedge(u,v); } break; } } if(!tag && len1>len2){ flag=0; break; } } if(!flag){ printf("Impossible\n"); continue; } int cnt=0; queue<int>Q; while(!Q.empty()){ Q.pop(); } for(int i=1;i<=sigma_size;i++) if(!in[i]) Q.push(i); while(!Q.empty()){ int u=Q.front(); Q.pop(); ans[cnt++]=u-1; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; --in[v]; if(!in[v]) Q.push(v); } } if(cnt != sigma_size) printf("Impossible\n"); else{ for(int i=0;i<sigma_size;i++) printf("%c",'a'+ans[i]); printf("\n"); } } return 0; }
codeforces 510C Fox And Names 拓扑
标签:拓扑排序
原文地址:http://blog.csdn.net/u011645923/article/details/43488333