拓扑排序模板题,本身没什么好说的,但是刘汝佳在白书中用到一个技巧,就是一个数组可以表示结点的三种状态:0代表未被访问过,1代表已经访问过,-1代表正在访问。
#include <iostream>
#include <string.h>
using namespace std;
int c[30], gra[30][30];
int topo[30], cnt;
int dfs(int u){
c[u] = -1; //设为负值,第3种状态
for(int v = 1; v <= 26; v++) if(gra[u][v]){
if(c[v] < 0) return 0; //环路
else if(!c[v] && !dfs(v)) return 0;
}
c[u] = 1;
topo[--cnt] = u;
return 1;
}
int toposort(){
cnt = 27;
memset(c, 0, sizeof(c));
for(int u = 1; u <= 26; u++) if(!c[u])
if(!dfs(u)) return 0;
return 1;
}
int main()
{
int n;
cin >> n;
char s[105][105];
for(int i = 1; i <= n; i++) cin >> s[i];
memset(gra, 0, sizeof(gra));
int flag = 1;
for(int i = 1 ;i <= n - 1; i++){
for(int j = 0; s[i][j] != '\0' || s[i + 1][j] != '\0'; j++){
if(s[i][j] == '\0') break;
if(s[i + 1][j] == '\0'){
flag = 0;
goto judge;
}
if(s[i][j] == s[i + 1][j]) continue;
else{
int a = s[i][j] - 'a' + 1, b = s[i + 1][j] - 'a' + 1;
gra[a][b] = 1;
break;
}
}
}
judge:if(!flag) cout << "Impossible" << endl;
else{
if(!toposort()) cout << "Impossible" << endl;
else{
for(int i = 1; i <= 26; i++)
cout << (char)(topo[i] + 'a' - 1);
}
}
return 0;
}
用好这种技巧,很多搜索问题都可以得到解决,代码也会更加简洁。