HDU 1285 确定比赛名次(拓扑排序)
Posted dwtfukgv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1285 确定比赛名次(拓扑排序)相关的知识,希望对你有一定的参考价值。
题意:你懂得。。。
析:先说一下什么是拓扑排序,就比如这个题,是u赢了v,把“赢了”关系看成是一条有向边,那么就得到了个有向图。
那么这个题就转化成了,把一个图的所有结点排序,使得每一条有向边(u,v)对应的u都排在v前面。并且字典序最小。
这样的问题,就称为拓扑排序。
首先先构造出一个图来,考虑每一个入度,和有向边,然后进行拓扑排序。
要遍历n次,每次找出入度为0的,然后输出,然后把相关的边去掉,继续查找。直到结束。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 500 + 10; int in[maxn], t; int G[maxn][maxn], n; void toposort(){ for(int i = 1; i <= n; ++i){ //遍历n次,每次找出一个入度为0的节点 for(int j = 1; j <= n; ++j){ if(!in[j]){//找出入度为0的节点 --in[j];//改变值,以防再次被找到 if(i == n) printf("%d\n", j); else printf("%d ", j); for(int k = 1; k <= n; ++k) if(G[j][k]) --in[k];//把与之相关的全改掉 break; } } } } int main(){ int m; while(~scanf("%d %d", &n, &m)){ int x, y; memset(G, 0, sizeof(G)); memset(in, 0, sizeof(in)); for(int i = 0; i < m; ++i){ scanf("%d %d", &x, &y); if(!G[x][y]){//一定要判重边啊,不然会一直WA G[x][y] = 1; ++in[y]; } } toposort(); } return 0; }
以上是关于HDU 1285 确定比赛名次(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章