codeforces #290 div1 A(拓扑排序)
2015-02-03 15:41:00
思路:比较明显的拓扑序问题。
扫描1~n-1,处理str[i]与str[i+1]第一个不相等的字符,建边。
然后就是跑一遍拓扑序,观察能否找满26个字母。
注意:坑点在于如果str[i+1]是str[i]的前缀,那么肯定是impossible!
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define MP(a,b) make_pair(a,b) 21 22 typedef long long ll; 23 typedef pair<int,int> pii; 24 const int INF = (1 << 30) - 1; 25 26 int n; 27 int ans[110],cnt,inc[110],len[110]; 28 char s[110][110]; 29 30 int first[110],ecnt; 31 struct edge{ 32 int v,next; 33 }e[110]; 34 35 void Add_edge(int u,int v){ 36 e[++ecnt].next = first[u]; 37 e[ecnt].v = v; 38 first[u] = ecnt; 39 } 40 41 bool Topo(){ 42 queue<int> Q; 43 while(!Q.empty()) Q.pop(); 44 FOR(i,0,25) if(inc[i] == 0) Q.push(i); 45 cnt = 0; 46 while(!Q.empty()){ 47 int x = Q.front(); Q.pop(); 48 ans[++cnt] = x; 49 for(int i = first[x]; ~i; i = e[i].next){ 50 int v = e[i].v; 51 inc[v]--; 52 if(inc[v] == 0) Q.push(v); 53 } 54 } 55 if(cnt < 26) return false; 56 return true; 57 } 58 59 int main(){ 60 MEM(first,-1); 61 ecnt = 0; 62 scanf("%d",&n); 63 REP(i,n){ 64 scanf("%s",s[i]); 65 len[i] = strlen(s[i]); 66 } 67 REP(i,n - 1){ 68 int j = i + 1; 69 int flag = 0; 70 int l = min(len[i],len[j]); 71 for(int p = 0; p < l; ++p){ 72 if(s[i][p] != s[j][p]){ 73 int o1 = s[i][p] - 'a'; 74 int o2 = s[j][p] - 'a'; 75 Add_edge(o1,o2); 76 inc[o2]++; 77 flag = 1; 78 break; 79 } 80 } 81 if(flag == 0 && len[j] < len[i]){ 82 printf("Impossible\n"); 83 return 0; 84 } 85 } 86 if(Topo() == false) printf("Impossible\n"); 87 else{ 88 REP(i,26) printf("%c",ans[i] + 'a'); 89 puts(""); 90 } 91 return 0; 92 }