【题目来源】: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();
}
}