确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8605 Accepted Submission(s): 3333
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
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。
相关推荐
**邻接表和逆邻接表是图论中两种重要的数据结构,用于高效地存储和操作图的信息。** **邻接表**是一种节省空间的图的存储方式,尤其适用于稀疏图(边的数量远小于顶点数量的平方)。在邻接表中,每个顶点都有一个...
在计算机科学和图论中,邻接矩阵和邻接表是两种常见的表示图的数据结构。本文将详细讨论这两种数据结构,以及如何在MATLAB中进行转换。我们将专注于标题和描述中提到的MATLAB程序,该程序能够将邻接表转换为邻接矩阵...
### 图的邻接表C++表示 在计算机科学领域,图是一种重要的数据结构,用于模拟对象之间的关系。根据图中的边是否具有方向性,可以将图分为无向图和有向图。对于稀疏图(即边的数量远小于顶点数量的平方),邻接表是...
在编程中,有多种方法来存储图,其中两种常用的方法是邻接矩阵和邻接表。这两种方法各有优缺点,适用于不同类型的图和不同的操作需求。 邻接矩阵是一种二维数组,其中的每个元素代表两个顶点之间是否存在边。如果...
在“C语言数据结构邻接表课程设计”中,我们将深入探讨如何利用C语言实现数据结构中的邻接表,这是图论中一个重要的抽象概念。邻接表是表示图的有效方式,尤其对于稀疏图(边的数量远小于顶点数量的平方)来说,它的...
本作业主要探讨如何将NFA转换为DFA,并通过数据结构——邻接表来实现这一过程。 非确定性有限自动机(NFA)是一种允许存在多种转移路径的自动机,它在读取输入符号时可以有多个可能的状态转移。NFA通常用五元组 (Q,...
【以邻接表的形式建立和存储图】 在图论中,图是由顶点(节点)和边(连接顶点的线)构成的数据结构。在计算机科学中,为了高效地存储和操作图,我们通常会使用不同的数据结构来表示图。其中,邻接表是一种常用的...
邻接表是实现有向图的一种常见且高效的数据结构。 邻接表由两部分组成:节点数组和边列表。对于一个包含n个节点的图,我们通常会有一个大小为n的数组,每个数组元素对应一个节点。数组中的每个元素又包含一个列表,...
完成“数据结构作业 邻接表”可能涉及以下内容:理解图的概念、邻接表的结构、如何用代码实现邻接表、以及如何使用邻接表进行DFS和BFS。通过这项作业,你可以深入理解数据结构的重要性,并提高解决实际问题的能力。...
在计算机科学中,我们通常使用两种主要的方法来存储图:邻接矩阵和邻接表。这两种方法各有优缺点,适用于不同的场景。 ### 邻接矩阵 **邻接矩阵** 是一种直观的图存储方式,它使用一个二维数组来表示图中的边。...
在数据结构领域,邻接表是一种非常重要的图数据结构,尤其适用于存储稀疏图,即边的数量远小于顶点数量的平方。本文将详细讲解邻接表的概念、优点以及如何用C++实现。 邻接表是由一系列顶点的链表组成,每个链表...
/*以下定义邻接表类型*/ typedef struct ANode /*弧的结点结构类型*/ { int adjvex; /*该弧的终点位置*/ struct ANode *nextarc; /*指向下一条弧的指针*/ InfoType info; /*该弧的相关信息,这里用于存放权值*/ }...
### 邻接表文本文档知识点解析 #### 一、邻接表概念与作用 在数据结构领域中,邻接表是一种非常重要的数据结构,主要用于表示图这种非线性结构。图是一种由顶点(节点)和边组成的数学结构,用于模拟现实世界中的...
邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历 邻接表深度遍历和广度遍历
邻接表法建立图程序代码 邻接表法是图的存储结构之一,通过建立邻接表来存储图的信息。在这里,我们将详细介绍邻接表法建立图程序代码的知识点。 图的定义 在图论中,图是由节点和边组成的。节点是图的基本元素,...
### 图的邻接表存储与C语言实现:深入解析 #### 核心概念与背景 在数据结构领域,图是一种非常重要的非线性数据结构,它由顶点集(Vertex Set)和边集(Edge Set)组成。在图中,顶点代表数据对象,而边则表示这些...
### 数据结构:图的邻接表存储 #### 一、引言 在计算机科学中,图是一种非线性数据结构,由顶点集合V和边集合E组成,表示为G=(V,E)。图可以用来表示各种各样的关系,如社交网络中的朋友关系、互联网中的网页链接等...
本主题将深入探讨“图”的一种高效表示方法——邻接表。 邻接表是图数据结构的一种高效实现,特别适用于稀疏图(边的数量远小于顶点数量的平方)。在邻接表中,每个顶点都有一个链表或数组,存储与之相连的所有顶点...
对于有向图,正向邻接表记录了每条边的起点,而逆邻接表则记录了每条边的终点。换句话说,逆邻接表为每个顶点存储了所有指向它的边的起点。这样,我们可以通过逆邻接表快速获取一个顶点的入度,即指向该顶点的边的...
本文将深入探讨一种用于表示图的数据结构——邻接表。邻接表是一种高效且节省空间的图表示方法,尤其适用于稀疏图(边的数量远小于顶点数量的平方)。 首先,我们需要了解图的基本概念。图是由顶点(或节点)和边...