确定比赛名次 【拓扑】
来源:互联网 发布:java权限管理如何实现 编辑:程序博客网 时间:2024/05/29 07:51
- 确定比赛名次
有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
思路 : 模版
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<map>#include<vector>#include<set>#define CLR(a,b) memset((a),(b),sizeof(a))#define inf 0x3f3f3f3f#define mod 100009#define LL long long#define M 505// 这里数组不能开的太大,否则内存超限#define ll o<<1#define rr o<<1|1#define lson o<<1,l,mid#define rson o<<1|1,mid+1,rusing namespace std;int mp[M][M];int topo[M];int in[M];int n,m;void toposort(){ int i,j; int next; int t=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) ///对于这种可能有多种排序的情况,它的前继点可能是有多个 { if(!in[j]) { next=j; break; } } // 接下来这个可以不用,因为寻找的时候本来就是从小的序号开始的 /*for(j;j<=n;j++) { if(!in[j]) next=min(next,j); }*/ topo[t++]=next; in[next]=-1; for(j=1;j<=n;j++) { if(mp[next][j]) in[j]--; } }}int main(){ while(~scanf("%d%d",&n,&m)) { int i,j; CLR(mp,0); CLR(in,0); for(i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); if(!mp[a][b]) /// 防止重边 { mp[a][b]=1; in[b]++; } } toposort(); printf("%d",topo[0]); for(i=1;i<n;i++) printf(" %d",topo[i]); putchar('\n'); } return 0;}
队列 topo
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<map>#include<vector>#include<set>#define CLR(a,b) memset((a),(b),sizeof(a))#define inf 0x3f3f3f3f#define mod 100009#define LL long long#define MAXN 500+100#define MAXM 250000+10#define ll o<<1#define rr o<<1|1#define lson o<<1,l,mid#define rson o<<1|1,mid+1,rusing namespace std;void read(int &x){ x=0;char c; while((c=getchar())<'0'); do x=x*10+c-'0';while((c=getchar())>='0');}struct Edge{ int from,to,next;}edge[MAXM];int in[MAXN];int head[MAXN],top;int n,m;void addedge(int a,int b) //防止重边 { int i,j; for( i=head[a];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(e.to==b) break; } if(i!=-1) return ; Edge e={a,b,head[a]}; edge[top]=e;head[a]=top++; in[b]++; // 防止重边}void init(){ memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); top=0;}void getmap(){ while(m--) { int a,b; cin>>a>>b; addedge(a,b); }}void topo(){ priority_queue<int , vector < int > , greater <int > > Q;//定义最小堆 top为最小的 for(int i=1;i<=n;i++) if(!in[i]) Q.push(i); int k=0; while(!Q.empty()) { int now=Q.top();Q.pop(); if(k++) putchar(' '); printf("%d",now); for(int i=head[now];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(--in[e.to]==0) Q.push(e.to); } } putchar('\n');}int main(){ while(~scanf("%d%d",&n,&m)) { init(); getmap(); topo(); } return 0;}
0 0
- 确定比赛名次 【拓扑】
- 拓扑排序-- 确定比赛名次
- HDOJ 1285:确定比赛名次 拓扑排序
- 【拓扑排序】 hdu1285 确定比赛名次
- hdu 确定比赛名次(拓扑排序)
- 确定比赛名次(拓扑排序)
- HDU 1285 拓扑排序 确定比赛名次
- HDU 1285 拓扑排序-- 确定比赛名次
- HDOJ1285 确定比赛名次(拓扑排序)
- 确定比赛名次 (拓扑排序)
- hdu 1285 确定比赛名次(拓扑排序)
- hdu1285 确定比赛名次 拓扑排序
- 确定比赛名次(hdu1285拓扑排序)
- hdu1285 确定比赛名次 (拓扑排序)
- HDU1285 确定比赛名次 拓扑排序
- hdu_1285 确定比赛名次 (拓扑排序)
- hdu1285-确定比赛名次-拓扑入门
- 拓扑排序——确定比赛名次
- MySQL表优化
- 第六章 JAVA方法初级学习
- 初识 Git
- linux初学 unit13 练习
- 51nod 1076 2条不相交路径(边双联通分量)
- 确定比赛名次 【拓扑】
- getCurrentSession()报Could not obtain transaction-synchronized Session for current thread错误
- lightoj1095 Arrange the Numbers 组合数学
- mysql explain用法
- 科锐课堂笔记:2017/4/12 单例模式与运算符重载
- getClass(),class属性和getName()解析
- 重载和重写的区别?
- Allegro的模块化设计
- 十六进制 0x1.2P5