1. 程式人生 > >codeforces 512A (拓撲排序)

codeforces 512A (拓撲排序)

題意:給出n個字串,問有沒有一種字元的替換方案使得所有的字串按照字典序遞增排列。

只要使得任意連續的兩個有序即可,如果字元a必須比字元b字典序小就建一條a到b的有向邊,然後通過一邊拓撲排序輸出結果即可。

#include <bits/stdc++.h>
using namespace std;
#define maxn 33

int in[maxn];
int g[maxn][maxn];
int n;
string a[105];

void add_edge (char a, char b) { 
    if (!g[a-'a'][b-'a']) in[b-'a']++;
    g[a-'a'
][b-'a'] = 1; return ; } bool build (int i, int j) { int l1 = a[i].length (), l2 = a[j].length (); for (int x = 0; x < min (l1, l2); x++) { if (a[i][x] != a[j][x]) { add_edge (a[i][x], a[j][x]); return 1; } } if (l2 <= l1) return 0; return
1; } queue <int> q; vector <int> ans; bool topo () { ans.clear (); while (!q.empty ()) q.pop (); int num = 0; for (int i = 0; i < 26; i++) if (!in[i]) { q.push (i); num++; } while (!q.empty ()) { int u = q.front (); q.pop (); ans.push_back (u); for
(int i = 0; i < 26; i++) if (g[u][i] && in[i]) { in[i]--; if (!in[i]) { q.push (i); num++; } } } if (num != 26) return 0; for (int i = 0; i < 26; i++) cout << (char)(ans[i]+'a'); cout << endl; return 1; } int main () { memset (g, 0, sizeof g); memset (in, 0, sizeof in); cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n-1; i++) { int j = i+1; bool ok = build (i, j); if (!ok) { cout << "Impossible" << endl; return 0; } } if (!topo ()) cout << "Impossible" << endl; return 0; }