码迷,mamicode.com
首页 > 编程语言 > 详细

HDU 1285 确定比赛名次(拓扑排序)

时间:2016-05-31 20:45:29      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

题意:你懂得。。。

析:先说一下什么是拓扑排序,就比如这个题,是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 确定比赛名次(拓扑排序)

标签:

原文地址:http://www.cnblogs.com/dwtfukgv/p/5547131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!