HDU 1285 -- 确定比赛名次 (拓扑排序)

题目大意:有N个队伍比赛,给出M行输赢关系,要求输出一个排名,符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

思路分析:利用小顶堆,直接进行拓扑排序就行。

代码实现:

邻接表:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int top,cnt,degree[510],out[510];
priority_queue<int,vector<int>,greater<int> > q;
struct Edge{
    int v;
    Edge *next;
}*head[510],e[250000];
void Addedge(int from,int to){
    Edge *p=&e[top++];
    p->v=to;
    p->next=head[from];
    head[from]=p;
}
void Tuopu(int n){
    for(int i=1;i<=n;i++){
        if(degree[i]==0)
        q.push(i);
    }
    while(!q.empty()){
        int a=q.top();
        out[cnt++]=a;
        q.pop();
        for(Edge *p=head[a];p;p=p->next){
            degree[p->v]--;
            if(degree[p->v]==0)
                q.push(p->v);
        }
    }
    printf("%d",out[0]);
    for(int i=1;i<cnt;i++)
        printf(" %d",out[i]);
    printf("\n");
}
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        memset(head,0,sizeof(head));
        memset(degree,0,sizeof(degree));
        top=0,cnt=0;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            Addedge(a,b);
            degree[b]++;
        }
        Tuopu(n);
    }
    return 0;
}

邻接矩阵:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=510;
priority_queue<int,vector<int>,greater<int> >q;
int cnt,map[maxn][maxn],degree[510],out[510];
void Tuopu(int n){
    for(int j=1;j<=n;j++){
        if(degree[j]==0){
            q.push(j);
        }
    }
    while(!q.empty()){
        int a=q.top();
        q.pop();
        out[cnt++]=a;
        for(int i=1;i<=n;i++){
            if(map[a][i]){
                degree[i]--;
                if(degree[i]==0)
                    q.push(i);
            }

        }
    }
    printf("%d",out[0]);
    for(int i=1;i<cnt;i++)
        printf(" %d",out[i]);
    printf("\n");
}
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        memset(map,0,sizeof(map));
        memset(degree,0,sizeof(degree));
        memset(out,0,sizeof(out));
        cnt=0;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            if(!map[a][b])//实验了很多次,一定要先判断这组关系是不是已经存在了,如果存在,b的入度就不变,否则会WA
                degree[b]++;
            map[a][b]=1;
        }
        Tuopu(n);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值