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 }

 

posted @ 2015-02-03 16:11  Naturain  阅读(106)  评论(0编辑  收藏  举报