HDU1285---确定比赛名次 (拓扑排序)

来源:互联网 发布:阿沁的淘宝店铺叫什么 编辑:程序博客网 时间:2024/06/05 12:39

【题目来源】:https://vjudge.net/problem/HDU-1285
【题意】
给出n个人,每人对应一个1~n的编号,如果比赛x赢y了,就在输入数据里表示为x y,问最终比赛名次是什么。
【思路】
有关于图论的排序,并且还是在拓扑排序专题题遇到,那肯定是拓扑排序啦(后者比较关键0.0),来一发裸模板,大致说一下,这个模板得来源。
假设现在有那么一个图:
这里写图片描述
说一下入度和出度的概念,入度是指一个定点通往其他点的条数,出度就是其他点到该点的条数(浅显易懂)。这个模板就是很简单的统计一下各个点的入度,每次去掉入度为0的,去掉之后,连同他所有的出度也去掉,这样一步一步,就拍完了序,按照这个图来说,就是先去掉1(为啥不去掉4呢,4也是入度为0呀,,因为题目中有说从小到大),去掉1之后,2的入度就成了0,同理可得:1 2 4 3。
【代码】

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;int ranks[500+10];int relax[500+10][500+10],in_degree[500+10];//in_degree[]数组记录的是入度,relax数组记录的是关系。int n,m;void to_sort(){    int tot=0,k;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(in_degree[j]==0)            {                ranks[tot++]=j;                in_degree[j]=-1;                k=j;                break;            }        }        for(int j=1;j<=n;j++)        {            if(relax[k][j])            {                relax[k][j]=0;                in_degree[j]--;            }        }    }    for(int i=0;i<tot;i++)    {        if(i) printf(" ");        printf("%d",ranks[i]);    }    printf("\n");}int main(){    while(~scanf("%d%d",&n,&m))    {        memset(relax,0,sizeof(relax));        memset(in_degree,0,sizeof(in_degree));        while(m--)        {            int node1,node2;            scanf("%d%d",&node1,&node2);            if(!relax[node1][node2])            {                relax[node1][node2]++;            }            in_degree[node2]++;        }        to_sort();    }}

当然,也可以在找谁和谁是对应的关系进而in_degree减一的时候,使用邻接表,或者因为找in_degree最小值得,所以完全可以用优先队列等等、
【代码】//邻接表

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;int ranks[500+10];int in_degree[500+10];//in_degree[]数组记录的是入度struct node{    int to,next;}relax[2500+10];int first[500+10];int n,m,num;void to_sort(){    int tot=0,k;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(in_degree[j]==0)            {                k=j;                in_degree[k]=-1;                break;            }        }        ranks[tot++]=k;        for(int j=first[k];j!=-1;j=relax[j].next)        {            in_degree[relax[j].to]--;        }    }    for(int i=0;i<tot;i++)    {        if(i) printf(" ");        printf("%d",ranks[i]);    }    printf("\n");}int main(){    while(~scanf("%d%d",&n,&m))    {        memset(in_degree,0,sizeof(in_degree));        for(int i=1;i<=n;i++)        {            first[i]=-1;        }        num=0;        while(m--)        {            int node1,node2;            scanf("%d%d",&node1,&node2);            relax[num].to=node2;            relax[num].next=first[node1];            first[node1]=num++;            in_degree[node2]++;        }        to_sort();    }}