標籤:
題意:給出n串名字,表示字典序從小到大,求符合這樣的字串排列的字典序
先挨個地遍曆字串,遇到不相同的時候,加邊,記錄相應的入度
然後就是bfs的過程,如果某一點沒有被訪問過,且入度為0,則把它排入佇列中,並將它指向的節點的入度減去1
另外如果len[i]<len[i-1],說明第i個字串是i-1個字串的首碼,但是它還排在後面,這樣肯定不存在符合的字典序,直接輸出“Impossible”
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std;12 13 typedef long long LL;14 const int INF = (1<<30)-1;15 const int mod=1000000007;16 const int maxn=100005;17 18 int e[maxn],first[maxn],next[maxn],ans[maxn],len[maxn],vis[maxn],in[maxn];19 char s[105][105];20 int ecnt;21 22 void addedges(int u,int v){23 e[ecnt]=v;24 next[ecnt]=first[u];25 first[u]=ecnt;26 in[v]++;27 ecnt++;28 }29 30 int main(){31 32 // freopen("in.txt","r",stdin);33 // freopen("out.txt","w",stdout);34 int n;35 cin>>n;36 37 memset(first,-1,sizeof(first));38 for(int i=1;i<=n;i++){39 cin>>s[i];40 len[i]=strlen(s[i]);41 }42 43 44 int j;45 ecnt=0;46 for(int i=2;i<=n;i++){47 for(j=0;j<min(len[i],len[i-1]);j++){48 if(s[i-1][j]!=s[i][j]){49 addedges(s[i-1][j]-‘a‘,s[i][j]-‘a‘);50 break;51 }52 }53 if(len[i]<len[i-1]&&j==len[i]){54 printf("Impossible\n");55 return 0;56 }57 }58 59 60 memset(vis,0,sizeof(vis));61 62 for(int i=1;i<=26;i++){63 int jj=26;64 int j;65 for( j=0;j<26;j++){66 if(!vis[j]&&in[j]==0){67 vis[j]=1;68 ans[i]=j;69 for(int k=first[j];k!=-1;k=next[k]){70 in[e[k]]--;71 }72 jj=j;73 break;74 }75 }76 if(jj==26){//jj的值沒有發生改變,說明這 一點找不到符合的拓撲序 77 printf("Impossible\n");78 return 0; 79 }80 }81 82 for(int i=1;i<=26;i++)83 printf("%c",ans[i]+‘a‘);84 printf("\n");85 return 0;86 }View Code
codeforces 510 C Fox And Names【拓撲排序】