标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285思路:a队赢了b队,代表一个从a到b的有向边,对这个图求拓扑排序,如果有多个答案,按照数字升序输出。寻找拓扑序列,看代码注释。
Sample Input
Sample Output
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 600; int mp[N][N]; int edge[N]; int flag[N]; struct line { int exist; //代表当前边是否存在 int u; //边的起始点 int v; //边的终点 }; struct line l[N * N]; void debug(int *num, int n) { for (int i = 1; i <= n; i++) printf("%d%c", num[i], i == n ? ‘\n‘ : ‘ ‘); } int main() { int n, m; while (scanf("%d%d", &n, &m) != EOF) //n代表点的数目,m代表边的数目。 { for (int i = 0; i < m; i++) //边的输入 { scanf("%d%d", &l[i].u, &l[i].v); l[i].exist = 1; } for (int i = 0; i < n; i++) //循环n次寻找拓扑序列 { for (int j = 1; j <= n; j++) //flag[i]代表第i个点是否为入度为0的点 flag[j] = 1; for (int j = 0; j < m; j++) //如果有边的终点是j,那么flag[j]置零。 { if(l[j].exist == 1) flag[l[j].v] = 0; } for (int j = 0; j < i; j++) //已经加入拓扑序列的点也置零。 flag[edge[j]] = 0; //debug(flag, n); for (int j = 1; j <= n; j++) //从终点里选取一个数字最小的点。 { if (flag[j] == 1) { edge[i] = j; break; } } for (int j = 0; j < m; j++) //对于加入拓扑序列的这个点,删除其所在的边。 { if(l[j].u == edge[i]) l[j].exist = 0; } } for (int i = 0; i < n; i++) //拓扑序列已找到,输出即可。 printf("%d%c", edge[i], i == n - 1 ? ‘\n‘ : ‘ ‘); } return 0; }
标签:
原文地址:http://www.cnblogs.com/burning-flame/p/5514375.html