确定比赛名次 【拓扑】
2017-04-13 00:58
190 查看
确定比赛名次
有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
思路 : 模版
代码
队列 topo
代码
有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,r using 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 108cd (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,r using 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; }
相关文章推荐
- hdu 1285 确定比赛名次(给一个拓扑有序图要求输出拓扑有序序列)
- 确定比赛名次(map+邻接表 邻接表 拓扑结构 队列+邻接表)
- A - 确定比赛名次(拓扑)
- A - 确定比赛名次(拓扑)
- hdu 1285 确定比赛名次【拓扑】
- 【HDU】1285 - 确定比赛名次(拓扑)
- hdu 1285 确定比赛名次 (拓扑算法)
- 【HDU】1285--确定比赛名次(拓扑&&优先队列)
- hdu1285(确定比赛名次)初学拓扑
- 确定比赛名次 hdu 拓扑输出字典序最小解
- HDU 1285 确定比赛名次【拓扑】
- hdoj 1285 确定比赛名次【拓扑】
- hdu 1285 确定比赛名次 (拓扑)
- hdu——1285——确定比赛名次(拓扑)
- HDU 1285-确定比赛名次(裸拓扑||拓扑+前向星)
- HDU 1285 确定比赛名次(拓扑排…
- (hdu step 5.2.5)确定比赛名次(求拓扑序列)
- hdu1285-确定比赛名次-拓扑入门
- hdu 1285 确定比赛名次(拓扑)
- hdoj1285 确定比赛名次(topo序列)模板