杭电1285拓扑排序解题报告
2013-05-30 10:49
323 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1285
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K
(Java/Others)
Total Submission(s): 4953 Accepted Submission(s):
1832
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
Author
SmallBeer(CML)
Source
杭电ACM集训队训练赛(VII)
Recommend
lcy
简单的拓扑排序但是我很水所以做了好久啊。。现在还是没什么掌握。。acm不是那么容易的。。加油吧。
#include<stdio.h>
#include<string.h>
int arc[501][501]; //邻接矩阵
int n,m,top;
int vis[501]; //标记访问过了没
int index[501];//标记入度
void init()
{
int i;
int a,b;
memset(vis,0,sizeof(vis));
memset(index,0,sizeof(index));
memset(arc,0,sizeof(arc));
for(i=1;i<=m;i++)
{
scanf("%d %d",&a,&b);
if(!arc[a])// 因为有可能出现重边,所以前面初始为0
{
arc[a][b]=1;
index[b]++; //b的入度加1因为a是大于b的即a指向b从a到b(b是弧尾);
}
}
}
void topsort()
{
int
i,j;
while(top<n)
{
for(i=1;i<=n;i++)
if(index[i]==0&&!vis[i])
//每一次都可以找到入度为0的点
break; //入度为0,并且i最小,一定可以排在最前面
vis[i]=1;
if(top)
//设置一个top是为了控制数据之间的空格;(第一个数据前面没有多余的空格,最后一个数据之后也没有多余的空格)
printf("
");
printf("%d",i);
top++;
for(j=1;j<=n;j++)
{
if(arc[i][j])
index[j]--;//把以i为起点j为终点的入度减1
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init(); //调用函数进行数据的输入以及初始化数组;
top=0;//设置一个top是为了控制数据之间的空格;(第一个数据前面没有多余的空格,最后一个数据之后也没有多余的空格)
topsort();//调用函数进行拓扑排序;
printf("\n");//调用结束后有一个空行哦
}
return
0;
}
有重新写了下,感悟挺多的(参考别人的)。。2012.7.23
#include<stdio.h>
#include<string.h>
[b]int map[502][502],indegree[502],n,m,pur[502];
void topsort()
{
int i,j,k=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(indegree[j]==0)//当入度为0时
{
indegree[j]--;//入度-1
pur[k++]=j;//
for(int x=1;x<=n;x++)
{
if(map[j][x])//以该顶点为弧尾的度数-1
indegree[x]--;
}
break;//这个还不能少,当把该顶点的相关弧尾的入度-1全部处理完后要进行下一个
}
}
}
}
int main()
{
int i;
while(scanf("%d
%d",&n,&m)!=EOF)//输入n,m(n表示队伍的个数,m表示接着有m行的输入数据)
{
memset(map,0,sizeof(map));//清零
memset(indegree,0,sizeof(indegree));
int a,b;
for(i=1;i<=m;i++)//m表示接着有m行的输入数据
{
scanf("%d
%d",&a,&b);
if(!map[a][b])//一开始都是没有访问过的[memset(map,0,sizeof(map));//清零]
{
map[a][b]=1;//标记访问过了
indegree[b]++;//弧尾(b)入度+1
}
}
topsort();//进行拓扑排序
for(i=1;i<=n;i++)
{
if(i!=n)//最后一个数的后面没有空格
printf("%d
",pur[i]);
else
printf("%d\n",pur[i]);
}
}
return 0;
}
相关文章推荐
- hdu 1285 确定比赛名次 拓扑排序 解题报告
- 解题报告-HDOJ-1285(拓扑排序)
- [解题报告]hdoj1285(拓扑排序)
- 杭电2041解题报告
- 杭电OJ1466动态规划经典题(解题报告)
- 杭电acm1008 hdu-acm-1008解题报告
- 杭电acm1232 hdu-acm-1232畅通工程解题报告
- 杭电2059解题报告
- 杭电 HOJ 1547 Bubble Shooter 解题报告
- 杭电5247找连续数 解题报告
- 杭电1045解题报告
- 杭电3342解题报告
- 杭电2044解题报告
- 杭电OJ 1671解题报告(字典树模板)
- 杭电acm1021 hdu-acm-1021解题报告
- Poj Window Pains (拓扑排序) 解题报告
- 130723杭电ACM多校第一场解题报告
- 杭电acm1012 hdu-acm-1012解题报告
- 杭电 2899 题解题报告
- 杭电1160解题报告