今天在看小白书的时候,看到了topsort(拓扑排序)。较之以前的做法,有所不同。
之前的做法是,找入度为0的往前放。新学的一种是,出度为0的往后放。
所以,两种方法为:
1.入度为0的结点,往前放。
2.出度为0的结点,往后放。
拿一道例题来:UVA 10305 Ordering Tasks
典型的topsort(拓扑排序)问题。
1.入度为0的结点,往前放。Code:
<span style="font-size:18px;">#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 105;
int enter[N], ans[N];
bool vis[N], map[N][N];
int n, m;
void topsort()
{
int top = 1;
while(1){
int _enter0 = -1;
for(int i = 1; i <= n; i ++){
if(!vis[i] && enter[i] == 0){
_enter0 = i;
break;
}
}
if(_enter0 == -1) break;
for(int i = 1; i <= n; i ++){
if(map[_enter0][i]){
enter[i] --;
}
}
vis[_enter0] = true;
ans[top ++] = _enter0;
}
return ;
}
int main()
{
while(scanf("%d %d", &n, &m) && (n || m)){
int x, y;
memset(enter, 0, sizeof(enter));
memset(vis, 0, sizeof(vis));
memset(map, 0, sizeof(map));
for(int i = 1; i <= m ; i ++){
scanf("%d %d", &x, &y);
map[x][y] = true;
enter[y] ++;
}
topsort();
for(int i = 1; i <= n; i ++){
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
}
return 0;
}</span>
2.出度为0的结点,往后放。Code:
代码是用dfs来实现的。用到一个结论:有向无环图一定存在拓扑序。
这也是算法导论上所说的深搜的方法。
<span style="font-size:18px;">#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 105;
int n, m, ans[N], top, vis[N];
bool map[N][N];
bool dfs(int u)
{
vis[u] = -1;
for(int v = 1; v <= n; v ++){
if(map[u][v]){
if(vis[v] == -1) return false;
if(!vis[v] && !dfs(v)) return false;
}
}
vis[u] = 1; ans[top --] = u;
return true;
}
bool topsort()
{
top = n;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i ++){
if(!vis[i] && !dfs(i)) return false;
}
return true;
}
int main()
{
// freopen("1.txt", "r", stdin);
while(scanf("%d %d", &n, &m) && (n || m)){
int x, y;
memset(map, 0, sizeof(map));
for(int i = 1; i <= m; i ++){
scanf("%d %d", &x, &y);
map[x][y] = true;
}
topsort();
for(int i = 1; i <= n; i ++){
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
}
return 0;
}</span>
------>
很好的又一种方法。涨知识。。