题目:
确定比赛名次 |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 337 Accepted Submission(s): 180 |
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 |
题目分析:
拓扑序列,简单题。
这里面也还有几道拓扑序列的题:http://blog.csdn.net/hjd_love_zzt/article/details/28700653
使用邻接矩阵AC的代码:
/* * e1.cpp * * Created on: 2015年3月8日 * Author: Administrator */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 505; int map[maxn][maxn];//连接情况.例如map[a][b]=1表示a与b连通 int indegree[maxn];//用于存储各点的入度 int queue[maxn];//最后的拓扑序列 int n;//点数 int m;//边数 int cnt;//拓扑序列中的节点数 /** * 求拓扑序列 */ void topo() { int i; int j; int k; for (i = 1; i <= n; ++i) {//枚举所有起点 for (j = 1; j <= n; ++j) {//枚举所有终点 if (indegree[j] == 0) {//如果某一终点的入度为0 indegree[j]--;//移除该点 queue[cnt++] = j;//将该点加入拓扑序列中 //将以该点为起点的所有边的终点的入度-1 for (k = 1; k <= n; ++k) { if (map[j][k] != 0) { indegree[k]--; } } break;//这个一定要有,否则会wa。break只对本层循环起作用。不对if-esle语句起作用 } //存在环的情况 if (j > n) { cout << "存在环" << endl; return; } } } } int main() { while (scanf("%d%d", &n, &m) != EOF) { memset(indegree, 0, sizeof(indegree)); memset(map, 0, sizeof(map)); cnt = 0; int i; for (i = 0; i < m; ++i) { int a, b; scanf("%d%d", &a, &b); if (map[a][b] == 0) {//去重.这道题可能存在重复数据。例如1 2这组数据出现多次 map[a][b] = 1; indegree[b]++; } } topo(); for (i = 0; i < cnt - 1; ++i) { printf("%d ", queue[i]); } printf("%d\n", queue[cnt - 1]); } return 0; }
使用链式前向星实现的拓扑排序,不过输出的顺序不符合这道题的题意,但是大家可以借此学一下
链式前向星的写法:
/* * e.cpp * * Created on: 2015年3月8日 * Author: Administrator */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 501; const int maxm = maxn * maxn; struct edge { int to; int weight; int next; } edge[maxm]; int head[maxn]; int indegree[maxn]; int n, m; void topo() { int queue[maxn]; int iq = 0; int i; for (i = 1; i <= n; ++i) { if (indegree[i] == 0) { queue[iq++] = i; } } for (i = 0; i < iq; ++i) { int k; for (k = head[queue[i]]; k != -1; k = edge[k].next) { indegree[edge[k].to]--; if (indegree[edge[k].to] == 0) { queue[iq++] = edge[k].to; } } } for(i = 0 ; i <= iq-2 ; ++i){ printf("%d ",queue[i]); } printf("%d\n",queue[iq-1]); // if (iq < n) { //如果iq的最终值小于n.说明拓扑序列不存在... // printf("T_T\n"); // printf("%d\n", n - iq); // } else { // printf("o(∩_∩)o\n"); // } } int main() { while (scanf("%d%d", &n, &m) != EOF) { memset(head, -1, sizeof(head)); memset(indegree, 0, sizeof(indegree)); int cnt = 0; int i; for (i = 1; i <= m; ++i) { int a; int b; scanf("%d%d", &a, &b); indegree[b]++; edge[cnt].to = b; edge[cnt].next = head[a]; head[a] = cnt++; } topo(); } return 0; }
时间: 2024-10-12 10:14:55