确定比赛名次 【拓扑】

来源:互联网 发布: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
原创粉丝点击