codeforces 510 C Fox And Names【拓扑排序】

题意:给出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)