`
Simone_chou
  • 浏览: 197464 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

确定比赛名次(邻接表)

    博客分类:
  • HDOJ
 
阅读更多

确定比赛名次

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8605    Accepted Submission(s): 3333

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

 AC:

#include<stdio.h>
#include<string.h>
int main()
{
	int n,m;
	int u[505],v[505],ind[505];
	int fir[505],fir_next[505];
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(ind,0,sizeof(ind));
		memset(fir,-1,sizeof(fir));
		for(int i=0;i<m;i++)
		{
		    scanf("%d%d",&u[i],&v[i]);
		    fir_next[i]=fir[u[i]];
		    fir[u[i]]=i;
		    ind[v[i]]++;
		}
				
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(!ind[j])
				{
					if(i==1) printf("%d",j);
					else printf(" %d",j);
					ind[j]=-1;
					for(int k=fir[j];k!=-1;k=fir_next[k])
					ind[v[k]]--;
					break;
				}
			}
		}
		printf("\n");
	}
	return 0;
}

   总结思路:

   补回之前未完成的邻接表版本,用u[i]表示出发点v[i]表示终点,fir[u]表示由u点出发的第一条边的编号,next[i]表示由编号为i的边的下一条边的编号,ind[v]表示v结点的入度;

   要理清楚每个变量,每个数组中的元素和下标所代表的含义;

   1、u [ i ]中的下标 i 是边的编号,代表一条边,而u[ i ]代表的是 i 这条边的起点,所以格式就是u[边]=点;

   2、v [ i ]中的下标 i 是边的编号,代表一条边,而v[ i ]代表的是 i 这条边的终点,所以格式就是v[边]=点

   3、fir[ u ]中的下标 u 是顶点的编号,代表一个点,而fir[ u ]代表的是以u顶点出发的第一条边(这样的话,fir数组代表的就是头结点),所以格式就是fir[点]=边

   4、next[ i ]中的下标 i 是边的编号,代表一条边,而next[ i ]代表的是 i 这条边的下一条边的编号,所以格式就是next[边]=边

   5、ind[ v ]中的下标 v 是终点的编号,代表一个点,而ind[ v ]代表的是以v顶点的入度,所以格式就是ind[点]=数量

   再分析代码:

1.输入部分:

 

memset(ind,0,sizeof(ind));
memset(fir,-1,sizeof(fir));
    for(int i=0;i<m;i++)
	{
	  scanf("%d%d",&u[i],&v[i]);
          fir_next[i]=fir[u[i]];
	  fir[u[i]]=i;
          ind[v[i]]++;
	}

    fir数组表示u顶点出发的第一条边,初始化全为-1代表从u顶点出发没有到哪个顶点,就是没有连哪条边。

    m次输入代表一共有m条边(没有判断重边的情况);

    第i条边,从u[i]出发到v[i];

    首先u[i]代表的是一个点,这个点是i号边的出发点;

    那么fir[u[i]]就是以u[i]这个点出发的第一条边;

    先将这条边赋值给fir_next[i],因为有新的边要添加进来;

    就是添加到以u[i]为头结点的链表里,但是添加的方式不是从后面添加,而是从前面添加

    就是一直以在u[i]第一条边的位置上插入新边,旧边往后退的形式添加;

    所以要先将这条旧边赋值到fir_next[i]中,代表i边的下一条边是几号边;

    赋值后,再改变fir[u[i]]=i;

    最后,这个点的入度增加1。

 

2.输出部分:

for(int i=1;i<=n;i++)
{
  for(int j=1;j<=n;j++)
   {
	if(!ind[j])
	  {
		if(i==1) printf("%d",j);
		else printf(" %d",j);
		ind[j]=-1;
//找到后消除这个顶点
		for(int k=fir[j];k!=-1;k=fir_next[k])
		ind[v[k]]--;
		break;
	  }
   }
}

    i循环n次,因为要排出n个序号出来;

    每一个位置再遍历一次,为了找寻入度为0的顶点出来;

    j代表的是顶点j;

    那fir[j]就是代表j出发的第一条边,所以k代表的以j顶点出发的边;

    当k==-1的时候就代表循环完了以j顶点为头结点的链表;

    k=fir_next[k]代表k边的下一条边;

    k是边,那么v[k]就是k边的终点,那ind[v[k]]代表的就是v[k]的入度;

    故以fir[j]出发的所有边所到达的终点入度都要-1。

分享到:
评论

相关推荐

    邻接表和逆邻接表的教程

    **邻接表和逆邻接表是图论中两种重要的数据结构,用于高效地存储和操作图的信息。** **邻接表**是一种节省空间的图的存储方式,尤其适用于稀疏图(边的数量远小于顶点数量的平方)。在邻接表中,每个顶点都有一个...

    adjacency matrix.zip_adjacency matrix_matlab 邻接表_matlab邻接表_邻接矩阵

    在计算机科学和图论中,邻接矩阵和邻接表是两种常见的表示图的数据结构。本文将详细讨论这两种数据结构,以及如何在MATLAB中进行转换。我们将专注于标题和描述中提到的MATLAB程序,该程序能够将邻接表转换为邻接矩阵...

    图的邻接表c++表示

    ### 图的邻接表C++表示 在计算机科学领域,图是一种重要的数据结构,用于模拟对象之间的关系。根据图中的边是否具有方向性,可以将图分为无向图和有向图。对于稀疏图(即边的数量远小于顶点数量的平方),邻接表是...

    实现图的邻接矩阵和邻接表存储

    在编程中,有多种方法来存储图,其中两种常用的方法是邻接矩阵和邻接表。这两种方法各有优缺点,适用于不同类型的图和不同的操作需求。 邻接矩阵是一种二维数组,其中的每个元素代表两个顶点之间是否存在边。如果...

    C语言数据结构邻接表课程设计

    在“C语言数据结构邻接表课程设计”中,我们将深入探讨如何利用C语言实现数据结构中的邻接表,这是图论中一个重要的抽象概念。邻接表是表示图的有效方式,尤其对于稀疏图(边的数量远小于顶点数量的平方)来说,它的...

    自动机nfa->dfa邻接表实现

    本作业主要探讨如何将NFA转换为DFA,并通过数据结构——邻接表来实现这一过程。 非确定性有限自动机(NFA)是一种允许存在多种转移路径的自动机,它在读取输入符号时可以有多个可能的状态转移。NFA通常用五元组 (Q,...

    以邻接表的形式建立和存储图

    【以邻接表的形式建立和存储图】 在图论中,图是由顶点(节点)和边(连接顶点的线)构成的数据结构。在计算机科学中,为了高效地存储和操作图,我们通常会使用不同的数据结构来表示图。其中,邻接表是一种常用的...

    有向图的构建(邻接表)

    邻接表是实现有向图的一种常见且高效的数据结构。 邻接表由两部分组成:节点数组和边列表。对于一个包含n个节点的图,我们通常会有一个大小为n的数组,每个数组元素对应一个节点。数组中的每个元素又包含一个列表,...

    数据结构作业 邻接表

    完成“数据结构作业 邻接表”可能涉及以下内容:理解图的概念、邻接表的结构、如何用代码实现邻接表、以及如何使用邻接表进行DFS和BFS。通过这项作业,你可以深入理解数据结构的重要性,并提高解决实际问题的能力。...

    图的邻接矩阵存储和邻接表存储

    在计算机科学中,我们通常使用两种主要的方法来存储图:邻接矩阵和邻接表。这两种方法各有优缺点,适用于不同的场景。 ### 邻接矩阵 **邻接矩阵** 是一种直观的图存储方式,它使用一个二维数组来表示图中的边。...

    简洁的邻接表

    在数据结构领域,邻接表是一种非常重要的图数据结构,尤其适用于存储稀疏图,即边的数量远小于顶点数量的平方。本文将详细讲解邻接表的概念、优点以及如何用C++实现。 邻接表是由一系列顶点的链表组成,每个链表...

    邻接表与邻接矩阵互换代码

    /*以下定义邻接表类型*/ typedef struct ANode /*弧的结点结构类型*/ { int adjvex; /*该弧的终点位置*/ struct ANode *nextarc; /*指向下一条弧的指针*/ InfoType info; /*该弧的相关信息,这里用于存放权值*/ }...

    邻接表文本文档

    ### 邻接表文本文档知识点解析 #### 一、邻接表概念与作用 在数据结构领域中,邻接表是一种非常重要的数据结构,主要用于表示图这种非线性结构。图是一种由顶点(节点)和边组成的数学结构,用于模拟现实世界中的...

    邻接表深度遍历和广度遍历.h

    邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历

    邻接表法建立图 程序代码

    邻接表法建立图程序代码 邻接表法是图的存储结构之一,通过建立邻接表来存储图的信息。在这里,我们将详细介绍邻接表法建立图程序代码的知识点。 图的定义 在图论中,图是由节点和边组成的。节点是图的基本元素,...

    图的邻接表存储C语言实现

    ### 图的邻接表存储与C语言实现:深入解析 #### 核心概念与背景 在数据结构领域,图是一种非常重要的非线性数据结构,它由顶点集(Vertex Set)和边集(Edge Set)组成。在图中,顶点代表数据对象,而边则表示这些...

    数据结构 图的邻接表存储

    ### 数据结构:图的邻接表存储 #### 一、引言 在计算机科学中,图是一种非线性数据结构,由顶点集合V和边集合E组成,表示为G=(V,E)。图可以用来表示各种各样的关系,如社交网络中的朋友关系、互联网中的网页链接等...

    数据结构 图 邻接表

    本主题将深入探讨“图”的一种高效表示方法——邻接表。 邻接表是图数据结构的一种高效实现,特别适用于稀疏图(边的数量远小于顶点数量的平方)。在邻接表中,每个顶点都有一个链表或数组,存储与之相连的所有顶点...

    逆邻接表快速实现拓扑排序

    对于有向图,正向邻接表记录了每条边的起点,而逆邻接表则记录了每条边的终点。换句话说,逆邻接表为每个顶点存储了所有指向它的边的起点。这样,我们可以通过逆邻接表快速获取一个顶点的入度,即指向该顶点的边的...

    简单的邻接表

    本文将深入探讨一种用于表示图的数据结构——邻接表。邻接表是一种高效且节省空间的图表示方法,尤其适用于稀疏图(边的数量远小于顶点数量的平方)。 首先,我们需要了解图的基本概念。图是由顶点(或节点)和边...

Global site tag (gtag.js) - Google Analytics