HDU - 1285 - 确定比赛名次 (拓扑排序,及其部分知识讲解)

Source::Click here

复杂度:拓扑排序的时间复杂度为O(V+E)。

遇到了一个写的不错的讲拓扑排序博客,以后忘了的话可以再看看。Click here

Sample Input

4 3
1 2
2 3
4 3

Sample Output

1 2 4 3

题意

这个题就是一个拓扑排序的模板题,只要清楚了解拓扑排序的操作过程,就很简单了。

题解

模板题,直接附上代码吧!具体模板代码的讲解都在注释里了!

                                                                                                                                                                                                                      

AC Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <functional>
#include <algorithm>
#define _USE_MATH_DEFINES
using namespace std;
typedef long long ll;
const int MAXN = 1e3+5;
int n, m;
int p[MAXN][MAXN];
int vis[MAXN];

void topsort()
{
    for(int i=1; i<=n; i++)//有n个点要输出,即循环n次。
    {
        for(int j=1; j<=n; j++)//题目要求小的编号在前,所以从1->n遍历
        {
            if(!vis[j])//当该点入度为0时,将该点输出。并将该点vis--(即将该点进行已经访问过的标记),同时删除与该点相连的边
            {
                vis[j]--;
                if(i==1) printf("%d",j);
                else printf(" %d",j);
                for(int k=1; k<=n; k++)
                {
                    if(p[j][k]) vis[k]--;
                }
                break;//(找到一个点后,即可break,进行下一次)
            }
        }
    }
    printf("\n");
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        memset(p,0,sizeof(p));
        memset(vis,0,sizeof(vis));
        int x, y;
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d",&x,&y);
            if(!p[x][y])
            {
                p[x][y] = 1;
                vis[y]++;
            }
        }
        topsort();
    }



    return 0;
}

猜你喜欢

转载自blog.csdn.net/Alibaba_lhl/article/details/81414355
今日推荐