hdu 1285 确定比赛名次
来源:互联网 发布:传世登陆器源码 编辑:程序博客网 时间:2024/06/03 09:51
注意:这道会重复输入同一个比赛,导致degree变大,要拦阻。
import java.util.Scanner;/* * 思想: * 把数据按要求连起来,就是1->2->3 * ----------------------- 4->3 * 这个时候就可以考虑把这道题看成图的遍历 * 于是想到用拓扑排序来输出拓扑序列,这样就瞒足题目了。 * 拓扑排序: * 若在有向图G中存在从顶点vi到vj的一条路径, * 则在顶点序列中顶点vi必须排在顶点vj之前。 * 每次搜索都要把当前结点的邻接的入度减一。 */public class Main {/* * 静态的成员变量相当于全局变量,这是语法问题。 * n,表示n个比赛队 * m,表示m场比赛 * arc-弧,用来保存每一个顶点的出边和入边,数据结构中是叫邻接矩阵。 * visited表示该顶点是否被访问,用0表示未访问,1表示已被访问 * degree表示该顶点的入度数目 */static Scanner sc = new Scanner(System.in);static int n, m;static int arc[][] = new int[501][501];static int visited[] = new int[501];static int degree[] = new int[501];public static void main(String[] args) {while (sc.hasNext()) {n = sc.nextInt();m = sc.nextInt();initialize();topoloySort();}}/* * topoloySort-拓扑排序 */private static void topoloySort() {int s = 0;while (s < n) {/** visited,0表示没有被访问,1表示已被访问* degree,表示当前结点的入度数目* 1)先找到入度为0的结点,入队列* 2)如果i==n,表明该有向图是循环图* 3)输出结果* 4)出队列,找到邻接结点*/int i = 0;for (; i < n; i++) {if (visited[i] == 0 && degree[i] == 0) {visited[i] = 1;break;}}if (i == n) {System.out.println("又向循环图");return;}s++;// 这个要写啊!不然死循环System.out.print(i + 1);if (s < n) {System.out.print(" ");}for (int j = 0; j < n; j++) {if (arc[i][j] == 1) {degree[j]--;}}}System.out.println();}/* * initialize-初始化 */private static void initialize() {// 初始化数据for (int i = 0; i < n; i++) {visited[i] = 0;degree[i] = 0;for (int j = 0; j < n; j++) {arc[i][j] = 0;}}// 输入数据,把剩下的数据初始化for (int i = 0; i < m; i++) {int a = sc.nextInt() - 1;int b = sc.nextInt() - 1;if (arc[a][b] == 0) {// 防止重复比赛arc[a][b] = 1;degree[b]++;}}}}
c++代码
/*一看题目就知道是拓扑排序题,用c++过。这道题m的大小是不确定的,可能会有重复输入,也就是队伍重新比赛。*/#include<iostream>using namespace std;/*这题要用邻接矩阵莱来记录比赛情况。i->j表示i赢j。arc表示临街矩阵degree表示入度visited表示该节点是否被访问*/int n,m;int arc[501][501];int degree[501];int visited[501];void topologySort(int count){ if(count==0){ return; } /* 第一步)找到入度为0的结点, 该节点必须是未被访问的,防止重复访问。 然后标记为1,表示该节点已近被访问。 第二步)输出该节点表示的值。 第三步)把该节点的邻居结点的入度减1。 第四步)循环调用指定次数,主要是把所有答案输出。 */ int i=1; for(;i<=n;i++){ if(degree[i]==0&&visited[i]==0){ visited[i]=1; break; } } if(i==n+1){ cout<<"又向循环图"<<endl; return; } cout<<i; if(count>1){ cout<<" "; }else{ cout<<endl; } for(int j=1;j<=n;j++){ if(arc[i][j]==1){ degree[j]--; } } topologySort(--count);}int main(){ while(cin>>n>>m){ /* 初始化数据 */ for(int i=1;i<=n;i++){ degree[i]=0; visited[i]=0; for(int j=1;j<=n;j++){ arc[i][j]=0; } } int a,b; for(int i=1;i<=m;i++){ cin>>a>>b; if(arc[a][b]==0){ /* arc[a][b]==0表示同一个比赛, 不能把入度的值加1。 b结点的入度加1 arc[a][b]表示a->b,a赢b。 */ degree[b]++; arc[a][b]=1; } } topologySort(n); } return 0;}
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16652 Accepted Submission(s): 6591
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 31 22 34 3
Sample Output
1 2 4 3
Author
SmallBeer(CML)
Source
杭电ACM集训队训练赛(VII)
0 0
- HDU 1285 确定比赛名次
- hdu 1285 确定比赛名次
- HDu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- HDU-1285-确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- hdu 1285 确定比赛名次
- Hdu 1285 确定比赛名次
- HDU 1285 确定比赛名次
- HDU 1285 确定比赛名次
- hdu 1285 确定比赛名次
- HDU 1285 确定比赛名次
- HDU - 1285 确定比赛名次
- nodejs与Express4配合搭建网站
- 小点滴——word自动目录+页码问题——摘自贴吧
- ipp sample cmake编译uic、application、picnic时需要Qt4(已安装Qt4.8.5)cmakelist.txt修改
- 计划策略-50-没有最终装配的计划
- 计划策略-52-没有最终装配和没有MTO的计划
- hdu 1285 确定比赛名次
- EnvironmentError:mysql config not found
- 玲珑杯Unity开发心得——开始菜单GUI制作
- 索引器
- java小总结
- Datatables从入门到精通(案例二)
- 手势识别器
- POJ 1087 A Plug for UNIX (最大流+多源多汇)
- POJ 2096 Collecting Bugs(概率DP)