标签:
题目链接:http://codeforces.com/contest/510/problem/C
题目大意:构造一个字母表,使得按照你的字母表能够满足输入的是按照字典序排下来。
递归建图:竖着切下来,将每个名字的第x个字母从上到下连接建图。然后求拓扑排序。
之所以要拓扑排序,因为要判断在x-1里面有a-->b 在x中有b-->a,这样就形成了一个环。这样一来,就不能够构造字母表了。
【经验教训】:在递归建图的函数中开了两个数组,用来记录字母第一次出现和最后一次出现的位置。。结果就RE在12上。。今后尽量不要在递归函数中开数组。。
1 #include <cstdio> 2 #include <algorithm> 3 #include <bitset> 4 #include <set> 5 #include <vector> 6 #include <iterator> 7 #include <cstring> 8 #include <map> 9 #include <cctype> 10 #include <iostream> 11 #include <string> 12 #include <stdexcept> 13 using namespace std; 14 15 int n; 16 string names[111]; 17 bool hasAns = true; 18 vector<int> G[33]; 19 int c[33],topo[33],t; 20 21 void solve(int l,int r,int x){ 22 if( l>=r ) return; 23 if( !hasAns ) return; 24 for(int i=l;i<=r;i++){ 25 if( x>=names[i].size() ) { 26 hasAns = false; 27 return; 28 } 29 int j = i+1; 30 for(;j<=r;j++){ 31 if( names[i][x]==names[j][x] ){ 32 continue; 33 } else { 34 break; 35 } 36 } 37 while( names[i].size()-1<x+1&&i<j-1 ) i++; 38 solve(i,j-1,x+1); 39 i = j-1; 40 } 41 42 for(int i=l;i<r;i++) { 43 if( names[i][x]==names[i+1][x] ) continue; 44 G[names[i][x]-‘a‘].push_back(names[i+1][x]-‘a‘); 45 } 46 } 47 48 bool dfs(int u){ 49 c[u] = -1; 50 for(int i=0;i<G[u].size();i++){ 51 int v = G[u][i]; 52 if( v<0 ) continue; 53 if( c[v]<0 ) return false; 54 else if(!c[v] && !dfs(v) ) return false; 55 } 56 c[u] = 1; topo[--t] = u; 57 return true; 58 } 59 60 bool toposort(){ 61 t = 26; 62 memset(c,0,sizeof(c)); 63 for(int u=25;u>=0;u--) if(!c[u]) 64 if(!dfs(u)) return false; 65 return true; 66 } 67 68 int main(){ 69 cin >> n; 70 for(int i=0;i<n;i++) cin >> names[i]; 71 solve(0,n-1,0); 72 if( !hasAns ) { 73 puts("Impossible"); 74 return 0; 75 } 76 bool hasAns = toposort(); 77 if( !hasAns ) { 78 puts("Impossible"); 79 return 0; 80 } 81 for(int i=0;i<26;i++){ 82 putchar(‘a‘+topo[i]); 83 } 84 puts(""); 85 86 return 0; 87 }
[CF #290-C] Fox And Names (拓扑排序)
标签:
原文地址:http://www.cnblogs.com/llkpersonal/p/4269677.html