- 总时间限制:
- 10000ms
- 内存限制:
- 1000kB
- 描述
给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前
- 输入
- 若干行整数,第一行有2个数,分别为顶点数v和弧数a,接下来有a行,每一行有2个数,分别是该条弧所关联的两个顶点编号
- 输出
- 若干个空格隔开的顶点构成的序列(用小写字母)
- 样例输入
6 8 1 2 1 3 1 4 3 2 3 5 4 5 6 4 6 5
样例输出
v1 v3 v2 v6 v4 v5
拓扑排序。
出自刘汝佳的算法入门经典。
#include<stdio.h> #include<string.h> const int MAXN = 200; int n, m, G[MAXN][MAXN]; int c[MAXN];// 0 白色。 -1 灰色 1 黑色。 int topo[MAXN], t; bool dfs(int u) { c[u] = -1;//正在访问。判回路。灰色。 for(int v = 1; v <= n; v++) if(G[u][v]) { if(c[v]<0) return false;//回路退出。 else if(!c[v]) dfs(v); } c[u] = 1; topo[t--]=u; return true; } bool toposort() { t = n; memset(c, 0, sizeof(c)); for(int u = 1; u <= n; u++) if(!c[u]) if(!dfs(u)) return false; return true; } int main() { while(scanf("%d%d", &n, &m)!=EOF) { memset(G, 0, sizeof(G)); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); G[v][u] = 1; //曾经以为这是反向边 废了好长时间了解。。其实这样才是正向边。= - 表示 v>u有一条路。 } toposort(); for(int i = n; i >=1; i--) printf(i==n?"v%d":" v%d", topo[i]); printf("\n"); } return 0; }