zoukankan      html  css  js  c++  java
  • 图论之初,拓扑排序、前向星(通过存储边来存储图)加优先队列对拓扑的优化-----hdu1285

    确定比赛名次

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 24193    Accepted Submission(s): 9763


    Problem Description
    有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
     

    Input
    输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
     

    Output
    给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。

    其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
     

    Sample Input
    4 3 1 2 2 3 4 3
     

    Sample Output
    1 2 4 3
    拓扑
    #include<queue>
    #include<stack>
    #include<math.h>
    #include<stdio.h>
    #include<numeric>//STL数值算法头文件
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<functional>//模板类头文件
    using namespace std;
    #define MAX 520
    int map[MAX][MAX]; //邻接矩阵
    int indegree[MAX]; //入度
    void toposort(int map[MAX][MAX],int indegree[MAX],int n)
    {
        int i,j,k=0;
        for(i=1; i<=n; i++) //遍历n次
        {
            for(j=1; j<=n; j++) //出入度为0的节点
            {
                if(indegree[j]==0)
                {
                    printf("%d%c", j, i == n ? '
    ' : ' ');
                    indegree[j]--;
                    k=j;
                    break;
                }
            }
            for(j=1; j<=n; j++) //删除与该节点关联的边
                if(map[k][j]==1)
                {
                    map[k][j]=0;
                    indegree[j]--;
                }
        }
    }
    int main()
    {
        int n,m; //n:关联的边数,m:节点数
        while(scanf("%d %d",&n,&m)==2&&n!=0)
        {
            int i;
            int x,y;
            memset(map,0,sizeof(map));
            memset(indegree,0,sizeof(indegree));
            for(i=1; i<=m; i++)
            {
                scanf("%d %d",&x,&y);
                if(!map[x][y])
                {
                    map[x][y]=1;
                    indegree[y]++;
                }
            }
            toposort(map,indegree,n);
        }
        return 0;
    }
    
    
    前向星(用存储边的方式存储图)加优先队列实现排序,列题在hdu 1285
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int INF = 1e9+7;
    const int VM = 503;// 点的个数
    struct node  //前向星的结构体
    {
        int v;//输队编号
        int next;
    };
    node edge[VM * 4];//结构体数组
    int head[VM];//头指针数组
    int cnt;//下标
    int deg[VM];//入度数组
    void toposort(int n)
    {
        priority_queue<int, vector<int>, greater<int> > que;//优先队列
        for (int i = 1; i <= n; i++)//找所有点
            if (deg[i] == 0)  //入度为 0
            {
                que.push(i);//加入队列
                deg[i]--;//入度 变为 -1
            }
        int k = 1;
        while (!que.empty())  //队列不为空
        {
            int u = que.top();//取出队首的数
            que.pop();//删除
            printf("%d%c", u, k++ == n ? '
    ' : ' ');//输出
            for (int i = head[u]; i != -1; i = edge[i].next)  //与该点相连的
            {
                node e = edge[i];//便于书写
                deg[e.v]--;//点的入度 -1
                if (deg[e.v] == 0)//若此点的 入度为 0
                    que.push(e.v);//放入队列
            }
        }
    }
    int main()
    {
        int n, m;
        int i;
        while (scanf("%d %d", &n, &m) == 2)  //多组输入,获取n,m
        {
            memset(head, -1, sizeof(head));//初始化
            memset(deg, 0, sizeof(deg));//初始化
            cnt = 0;//初始化
            while (m--)
            {
                int u, v;
                scanf("%d %d", &u, &v);//获取u,v
                for (i = head[u]; i != -1; i = edge[i].next)//查找重边
                    if (edge[i].v == v)//输入重复数据
                        break;//不再储存
                if (i == -1)  //若不是重复数据
                {
                    deg[v]++;//加度
                    edge[cnt].v = v;
                    edge[cnt].next = head[u];
                    head[u] = cnt++;
                }
            }
            toposort(n);//调用函数
        }
        return 0;
    }

  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/7264880.html
Copyright © 2011-2022 走看看