杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告

杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告

大家好,又见面了,我是全栈君。

杭州电子科技大学Online Judge 确定比赛名次(ID1285解题报告
巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo

 

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

 

算法分析: 

本题是拓扑排序的典型应用。

因为顶点数量不多,能够採用邻接矩阵来存储图信息,这样算法比較简单,仅仅须要搜索n次,每次把序号最小的入度为0的顶点存储到拓扑序列中即可了。算法思路比較清晰。代码也比較简洁。但时间复杂度和空间复杂度都较高。

还有一种方法是採用邻接表存储图信息。因为题目要求输出时编号小的队伍在前,所以在入栈时一定要保证先让序号最小的入度为0的顶点在栈顶,这样依据后进先出的特点,能够把序号最小的顶点存储到拓扑序列中。我採用折半插入排序的方法。把入度为0的顶点按递减序排序,然后对图进行深度优先搜索,能获得正确的拓扑序列。

本算法时间复杂度和空间复杂度都非常好。可是代码较长。

两种算法都给出代码,大家能够比較一下。并请提出宝贵意见。

说明: 

算法思想:拓扑排序,折半插入。

数据结构:邻接矩阵。邻接表。

时间复杂度:算法1O(N^2);当中N为顶点数量;

       算法2O(N+M);当中N为顶点数量。M为边的数量

 

空间复杂度:算法1O(MAXN^2);当中MAXN为最大顶点数量;

算法2O(MAXN +M);当中MAXN为最大顶点数量;M为边的数量。

Run ID

Submit Time

Judge Status

Pro.ID

Exe.Time

Exe.Memory

Code Len.

Language

Author

 

12236157

2014-11-19 14:09:06

Accepted

1285

31MS

1232K

C

巧若拙

12235820

2014-11-19 13:07:33

Accepted

15MS

460K

4004 B

C

巧若拙

 

代码例如以下:

算法1

#include<stdio.h>

#include<stdlib.h>

 

#define MAXN 502   //最大顶点数量

 

int map[MAXN][MAXN] = {0};

 

void TopoLogicalSort(int n);

 

int main()

{

    int i, j, m, n, u, v;

 

    while(scanf(“%d%d”, &n,&m) != EOF)

       {  

           for (i=0; i<MAXN;i++)

                  for (j=0; j<MAXN; j++)

                         map[i][j] = 0;

          

              for (i=0; i<m; i++)       

              {

                     scanf(“%d%d”, &u, &v);

                     if (map[u][v] == 0)    //数据可能会反复

                     {

                            map[u][v] = 1;

                            map[0][v]++; //存储顶点v的入度

                     }

              }

             

              TopoLogicalSort(n);

    }

        

    return 0;

}

 

void TopoLogicalSort(int n)

{

    int i, j, top;

    int topo[MAXN] = {0};

   

    for (top=0; top<n; top++)//总共同拥有n个顶点,搜索n

    {

           for(i=1; i<=n; i++)//寻找入度为0的序号最小的顶点

           {

                  if(map[0][i] == 0)

                  {

                         map[0][i]= -1;

                         break;

                  }

           }

           topo[top]= i;

           for(j=1; j<=n; j++) //弧尾i相应弧头j入度减1

           {

                  if(map[i][j] == 1)

                         map[0][j]–;

           }

    }

   

    for (i=0; i<top-1; i++)

    {

           printf(“%d”, topo[i]);

    }

    printf(“%d\n”, topo[top-1]);

}

 

算法2

#include<stdio.h>

#include<stdlib.h>

 

#define MAXN 510   //最大变量(顶点)数量

 

typedef int VertexType; //顶点类型由用户自己定义

typedef int EdgeType; //边上的权值类型由用户自己定义

 

typedef struct EdgeNode{ //边表结点

    int adjvex; //邻接点域,存储该顶点相应的下标

//    EdgeType weight; //权值,对于非网图能够不须要

    struct EdgeNode *next; //链域,指向下一个邻接点

} EdgeNode;

 

typedef struct VertexNode{ //顶点表结点

    VertexType data; //顶点域,存储顶点信息

    int in;  //存储顶点入度的数量

    EdgeNode *firstEdge; //边表头指针

} VertexNode;

 

void CreateGraph(VertexNode*GL, int n, int m);//把顶点和边信息读入到表示图的邻接表中

int InsertStack(int vec[],int x, int n);//折半插入,递减排序

voidTopoLogicalSort_DFS(VertexNode *GL, int n);

 

int main()

{

    int i, m, n;

    VertexNode GL[MAXN];

   

    while(scanf(“%d%d”, &n,&m) != EOF)

       {  

           CreateGraph(GL, n,m);//把顶点和边信息读入到表示图的邻接表中

          TopoLogicalSort_DFS(GL, n);

    }

        

    return 0;

}

 

void CreateGraph(VertexNode*GL, int n, int m)//把顶点和边信息读入到表示图的邻接表中

{

    int i, u, v;

    EdgeNode *e;

 

    for (i=1; i<=n; i++)//初始化图

    {

        GL[i].data = i;

        GL[i].in = 0;

        GL[i].firstEdge = NULL;

    }

   

    for (i=0; i<m; i++)

    {

        e = (EdgeNode*)malloc(sizeof(EdgeNode));//採用头插法插入边表结点

        if (!e)

        {

            puts(“Error”);

            exit(1);

        }

       

        scanf(“%d%d”, &u,&v);

        e->next = GL[u].firstEdge;

        GL[u].firstEdge = e;

        e->adjvex = v;

        GL[v].in++;

    }

}

 

int InsertStack(int vec[],int x, int n)//折半插入,递减排序

{

       int low = 0, high = n – 1, mid, j;

 

    while(low <= high) //折半查找插入位置

    {

              mid = (low + high)/2;

              if(vec[mid] < x)

              {

                     high = mid -1;

              }

              else

              {

                     low = mid + 1;

              }

       }

    //进行插入操作

    for(j=++n; j>low; j–)

    {

        vec[j] = vec[j-1];

    }

    vec[low] = x;

   

    return n;

}

 

voidTopoLogicalSort_DFS(VertexNode *GL, int n)

{

    int i, u, v, top = 0;

    int count = 0;

    EdgeNode *e;

    int topo[MAXN], Stack[MAXN];//有序栈(或优先队列)

   

    for (i=1; i<=n; i++)//将入度为0的顶点按序号大小逆序入栈

    {

        if (GL[i].in == 0)

        {

             top = InsertStack(Stack, i, top);

        }

    }

    

    while (top > 0)//採用深度优先搜索获取拓扑序列

    {

        u = Stack[–top];

        topo[count++] = u;

       

        for (e=GL[u].firstEdge; e!=NULL;e=e->next)//u的邻接点入度减1,并将入度为0的顶点入栈

        {

            v = e->adjvex;

            if (–GL[v].in == 0)

            {

                   top= InsertStack(Stack, v, top);

            }

        }

    }

   

    for (i=0; i<count-1; i++)

    {

           printf(“%d”, topo[i]);

    }

    printf(“%d\n”, topo[count-1]);

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115972.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…[通俗易懂]

    红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…[通俗易懂]各位读者,知识无穷而人力有穷,所以,要么改需求,要么找专业人士,要么自己研究。大家可以点赞、收藏、关注、评论我啦、需要完整文件随时联系我或交流哟~!

    2022年6月29日
    26
  • 【转】物业管理与移动互联网科技|微信公众平台,物业app,物业O2O[通俗易懂]

    【转】物业管理与移动互联网科技|微信公众平台,物业app,物业O2O[通俗易懂]【导语】当下,物业管理行业正在接受新科技浪潮的冲击和洗礼,业界企业纷纷探索物业服务的新发展模式。云服务、微社区、微信公众平台、app等,这些本来陌生的词汇在物业管理行业变得耳熟能详。在借助科技手段拓展多种经营,提升竞争力、增加创富能力、开展信息化建设和管理的同时,部分物业服务企业的发展模式和理念又提升了一大步,现代科技推动物业管理行业发展正在成为现实。第一部分:移动互联网改变传统物业管…

    2022年6月22日
    18
  • 6.25科技新闻4

    6.25科技新闻4Lytro光场相机体验评测Lytro光场相机是一款可以先拍照,后对焦的相机。当时一出现就引起挺大的反响的,现在就随小编一起来体验一下这款光场相机吧! 关于光场相机的外观,小编不再累述了。各位可以到之前的《先拍后对焦LYTRO光场相机图赏》里面观看完整外观图。 首先我们来看看官方介绍:小编大概把图中的意思翻译了一下,翻译都在图上,看

    2022年6月5日
    129
  • 电子科技大学考研真题在哪找_二本电子科技大学排名

    电子科技大学考研真题在哪找_二本电子科技大学排名全局目录说明:电子科技大学计算机专业基础专业的科目代码2003年是429,2005年不详,2006年改为413,2008年改为820。电子科技大学信息与软件工程学院、计算机科学与工程学院、电子科学技术研究院、自动化工程学院均考此科目。2014年电子科技大学820计算机专业基础考研真题电子科技大学20U年攻读硕士学位硏究生入学考试试题考试科目:820计算机专业基础注:所有答秦必须写…

    2022年8月30日
    3
  • 【金融科技前沿】【长文】金融监管、监管科技以及银行业监管报送概述「建议收藏」

    【金融科技前沿】【长文】金融监管、监管科技以及银行业监管报送概述「建议收藏」上周金融科技前沿课程的主题是《监管科技》,韩海燕老师从金融监管引入,介绍了我国的金融监管体系,接着进入监管科技的详细讲解。我觉得最主要的是弄清楚监管科技的定义,以及在实际的银行业应用场景中具体的运作流程是怎么样的。韩老师讲的很全面,将ABCD等金融科技手段在监管系统中是如何运作的讲的很清楚,收获颇丰,但是比较少涉及到监管的对象和内容,仍没有很清楚监管机构是要监管什么东西?监管机构要求银行金融业机构报送的资料有哪些?这些报送要求的目的分别是什么?所以这篇文章分为三个部分,一是介绍金融监管,二是介绍监科技,三.

    2022年5月6日
    267
  • 焦点科技怎么老是招人_选错对焦点,错失好照片,你了解相机的对焦吗?

    焦点科技怎么老是招人_选错对焦点,错失好照片,你了解相机的对焦吗?对焦一直是衡量相机的性能的重要参数,在很长的一段时间里,我们因为相机的对焦系统不够强大,而习惯的单点手动设置对焦。而近几年微单相机的对焦快速发展,眼部自动对焦已经比较成熟,而我们的习惯也应该发生改变……选错对焦点,错失好照片多好的构图,妹子笑的多甜,然而就是因为焦点没有对准,成功的变成一张废片。很多人和我抱怨过,什么镜头跑焦,机身跑焦,可是你们有没有从自身找过原因,当真找到正确的焦点,准确合…

    2022年6月6日
    328

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号