在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological sorting)。
每个顶点出现且只出现一次;
若A在序列中排在B的前面,则在图中不存在从B到A的路径。
也可以定义为:拓扑排序是对有向无环图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面[1]。
摘自维基百科
hdu1285
题意
拓扑排序模板题,输出时要求在满足条件的情况下小的编号在前
code(DFS实现,错误)
DFS有问题,无法保证小的编号在前。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 505;
int n, m;
int c[MAXN]; // 表示当前点的状态 -1:正在访问 1:已访问 0:未访问
vector<int> G[MAXN];
int sta[MAXN], top;
bool dfs(int u)
{
c[u] = -1;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(c[v] < 0) return false; // 存在环
if(!c[v] && !dfs(v)) return false;
}
c[u] = 1;
sta[--top] = u;
return true;
}
bool toposort()
{
top = n;
memset(c, 0, sizeof c);
for(int i = 1; i <= n; i--) // 点 1...n
if(!c[i] && !dfs(i)) return false;
return true;
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i <= n; i++) G[i].clear();
for(int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
G[x].push_back(y);
}
toposort();
for(int i = 0; i < n; i++)
printf("%d%c", sta[i], i == n - 1 ? '
' : ' ');
}
return 0;
}
code(优先队列实现)
#include <iostream>
#include <cstdio>
#include <cstring>
#include<queue>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 505;
int n, m;
int c[MAXN];
vector<int> G[MAXN];
vector<int> topolist;
int toposort()
{
priority_queue<int, vector<int>, greater<int> > q;
for(int i = 1; i <= n; i++) if(!c[i]) q.push(i);
while(!q.empty())
{
int u = q.top(); q.pop();
topolist.push_back(u);
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(--c[v] == 0) q.push(v);
}
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i <= n; i++) G[i].clear();
memset(c, 0, sizeof c); topolist.clear();
for(int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
G[x].push_back(y);
c[y]++;
}
toposort();
for(int i = 0; i < n; i++)
printf("%d%c", topolist[i], i == n - 1 ? '
' : ' ');
}
return 0;
}