******************************************************************************************************************
题解:
给你n个字符串(全小写),让你按照输入的顺序来个字母表排列,(就是改变字母表的某些字母位置,使得你的输入是按照新的字典序)
如果前一个是后一个的子串,那么前一个一定小于后一个所以可以跳过。反之,如果后一个是前一个的子串,无论字典序怎么改都无法成立就输出"Impossible"。
新的字典序就是按照2个字符串的不同首字母,构建的有向图。
在使用拓扑排序就可以了。
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <string>
6 #include <vector>
7 #include <map>
8 #include <set>
9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define mset(a, b) memset((a), (b), sizeof(a))
16 typedef long long LL;
17 const int inf = 0x3f3f3f3f;
18 const int maxn = 100+10;
19 string s[maxn];
20 int gap[30][30];
21 int c[30], topo[30], t;
22 bool dfs(int u)
23 {
24 c[u] = -1;
25 for(int v = 0; v<26; v++) if(gap[u][v]){
26 if(c[v] < 0 ) return false;
27 else if(!c[v] && !dfs(v)) return false;
28 }
29 c[u] = 1; topo[--t] = u;
30 return true;
31 }
32 bool toposort()
33 {
34 t = 26;
35 mset(c, 0);
36 for(int i=0;i<26;i++) if(!c[i])
37 if(!dfs(i)) return false;
38 return true;
39 }
40 int main()
41 {
42 int n;
43 cin >> n;
44 for(int i=0;i<n;i++) cin >> s[i];
45 for(int i=0;i<n-1;i++){
46 int len1 = s[i].size();
47 int len2 = s[i+1].size();
48 int p = 0;
49 while(p<len1 && p<len2 && s[i][p]==s[i+1][p]) p++;
50 if(p == len1 && len1 < len2) continue;
51 if(p == len2 && len2 < len1) {cout<<"Impossible"<<endl;return 0;}
52 if(gap[s[i][p]-'a'][s[i+1][p] -'a'] == 1) continue;
53 gap[s[i][p]-'a'][s[i+1][p]-'a']=1;
54 }
55 if(toposort()){
56 for(int i=0;i<26;i++)
57 printf("%c", topo[i]+'a');
58 }
59 else
60 cout <<"Impossible"<< endl;
61 return 0;
62 }
来源:https://www.cnblogs.com/denghaiquan/p/6668473.html