标签:
图的边的表示方法,有很多。像邻接矩阵、边集数组、邻接表等。其中,第三者的时空复杂度应该是最优的。但是实现却需要比较麻烦的链表,但是我们也可以用数组来模拟链表,使编程的复杂度进一步降低。
这种算法:遍历所有的边的时间复杂度是O(M),M表示边的总数,空间复杂度也是O(M)。在最坏情况下,查询i与j是否有边的时间复杂度是O(N)。
这篇文章主要写给P(Pascal)党,在Cpp中,链表的实现方式较为简单(有现成的库),所以也没必要用这种办法。说是模拟实现邻接表,其实是模拟实现链表。接下来看类型定义:
type E=record too,next,capa:longint;//(too 表示该条边指向的点,next表示该条边指向的下一条边,capa表示该条边的权值) end; var edge:array[1..100000] of E;//edge是边表 nedge:longint;//(表示总的边数) head:array[1..100000] of longint;//(head[i]表示第i个点的第一条边在边表的位置)
建树的过程如下(N个点,M条边):
procedure addedge(a,b:longint); begin inc(nedge); edge[nedge].next:=head[a]; edge[nedge].too=b;head[a]=nedge; end; //Main readln(n,m); nedge:=0; fillchar(head,sizeof(head),0); for i:=1 to M do begin read(a,b); addedge(a,b); addedge(b,a); end;
访问与k相邻的所有点:
t:=head[k]; while ( t>0) do begin v:=edge[t].too; t:=edge[t].next; end;
算法实现原理如下:建树时,找到上面那条边,把这条边“倒挂”在上面,遍历的时候,只要顺着扫过来就好了。
标签:
原文地址:http://www.cnblogs.com/Darksun/p/4322103.html