码迷,mamicode.com
首页 > 编程语言 > 详细

hdu1285 拓扑排序

时间:2016-09-28 22:50:35      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

思路:

选择一个入度为0的顶点并输出,从网中删除此顶点及所有出边。

循环结束后,若输出的定点数小于网中的顶点数,则输出有回路信息,否则输出的顶点就是一种拓扑序列。

具体实现方法:邻接表,时间复杂度较小,邻接矩阵,时间复杂度高

 

确定比赛名次

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 3

1 2

2 3

4 3

 

Sample Output

1 2 4 3

 

 

邻接矩阵实现:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;

int map[505][505];
int indegree[505];
int output[505];
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(map,0,sizeof(map));
        memset(indegree,0,sizeof(indegree));
        while(m--)
        {
            scanf("%d%d",&a,&b);
            if(map[a][b]==0)
            {
                map[a][b]=1;
                indegree[b]++;
            }
        }
        int i=0;
        while(i<n)
        {
            for(int j=1; j<=n; j++)
            {
                if(indegree[j]==0)
                {
                    indegree[j]--;
                    output[i++]=j;
                    for(int k=1; k<=n; k++)
                        if(map[j][k])
                        {
                            indegree[k]--;
                            map[j][k]=0;
                        }
                    break;
                }
            }
        }
        for(int i=0; i<n-1; i++)
            printf("%d ",output[i]);
        printf("%d\n",output[n-1]);
    }
    return 0;
}

邻接表实现:

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

//有向图的邻接表
typedef struct v
{
    int vex;//终点的序号
    v *next;//与这条有向边具有相同起点的其它有向边
} V; //边结点
typedef struct h
{
    int indegree;//入度
    v *next;//指向((从该节点出发的有向边的)边结点所组成的单链表)
} H; //头结点
H team[10010];
V *p;

int main()
{
    int i,n,m,a,b,count;
    priority_queue<int,vector<int>,greater<int> > q;
    while(cin>>n>>m)
    {
        memset(team,0,sizeof(team));
        while(m--)
        {
            //加入一条a->b的有向边
            cin>>a>>b;
            team[b].indegree++;
            p=new V;
            p->vex=b;
            p->next=team[a].next;
            team[a].next=p;
        }
        //输出拓扑排序
        for(i=1; i<=n; i++)
            if(team[i].indegree==0)
                q.push(i);
        count=0;
        while(!q.empty())
        {
            a=q.top();
            q.pop();
            if(count)
                cout<< ;
            cout<<a;
            count++;
            for(p=team[a].next; p!=0; p=p->next)
            {
                b=p->vex;
                if(--team[b].indegree==0)
                    q.push(b);
            }
        }
        cout<<endl;
    }
    return 0;
}

 

hdu1285 拓扑排序

标签:

原文地址:http://www.cnblogs.com/a-clown/p/5917946.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!