拓扑排序

花了一节课多的时间看完了拓扑排序的基本模板,顺带做了注解,终于理解了这个算法的实现。本题找每一层的结点的时候是按照从上向下,从左往右的顺序删除的,因为输入的时候已经确定了数据的大小关系,也就是在寻找入度为零的点的时候是从小到大检索的,如果从大往小检索,就会先深入一侧,再横向搜索,就像树的深度搜索一样?。。(表示疑惑)。。

下面给出题目

 

确定比赛名次

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

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
 
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define maxx 505
 7 //degree[]  每个结点的入度
 8 //f[]   每个结点所在的层
 9 int degree[maxx];
10 int f[maxx];
11 int top;
12 int map[maxx][maxx];
13 int n,m;
14 struct node
15 {
16     int p;
17     int top;
18 } po[maxx];
19 void Toplogical_sort()
20 {
21     int i,j;
22     bool p=true;还有数据可以操作
23     top=0;处于第几个层次
24     int tmp;当前位置
25     while(p)如果还有可以操作的
26     {
27         p=false;把这个点去掉
28         top++;到下一层
29         tmp=0;暂时的tmp,为了跳出循环还有i存在
30         for(i=1; i<=n; i++)循环找入度为零的点
31             if(degree[i]==0)找到
32             {
33                 p=true;修改成有数据可以继续操作
34                 f[i]=top;当前数据在第几层
35                 tmp=i;tmp改成当前数据推出
36                 break;
37             }
38         for(j=1; j<=n; j++)找该点的后继有向箭头
39             if(map[tmp][j])找到
40                 degree[j]--;入度减一
41         degree[tmp]=-1;把当前结点置负,也就是消失
42     }
43     top--;没有入度为零的点了,都是负一了,要把最后一个加上多余的一层去掉,最后一个循环什么都没做但是top加1了
44 }
45 int cmp(struct node a,struct node b)
46 {
47     return a.top<b.top;
48 } 比较层次的大小
49 int main()
50 {
51     while(scanf("%d%d",&n,&m)!=EOF)
52     {
53         memset(map,0,sizeof(map));
54         memset(degree,0,sizeof(degree));
55         memset(f,0,sizeof(f));清空
56         int a,b;
57         for(int i=1; i<=m; i++)循环输入数值
58         {
59             scanf("%d%d",&a,&b);
60             if(!map[a][b])
61             {
62                 map[a][b]=1;置为真
63                 degree[b]++;确定有几个入度
64             }
65         }全都输入完毕
66         Toplogical_sort();进行拓扑排序,将入度逐一删除,并确定每个数据的层次
67         for(int i=0; i<n; i++)
68         {
69             po[i].p=i+1;
70             po[i].top=f[i+1];
71         }赋值层次和数据,方便排序
72         sort(po,po+n,cmp);用sort排序,从小到大排序,层次越低越先
73         for(int i=0; i<n-1; i++)
74             printf("%d ",po[i].p);
75         printf("%d\n",po[n-1].p);输出
76     }
77     return 0;
78 }

模板来自http://blog.csdn.net/sdjzli/article/details/8639236

感谢!

posted @ 2015-03-23 17:14  kingofprank  阅读(171)  评论(0编辑  收藏  举报