2014年04月27日

时间:2022-08-22 14:04:33
                        据说是最高效的邻接表....
别误会,小人只是个渣,这里不自量力下,昨天刚向老蔡学的,给出我的理解 2014年04月27日2014年04月27日

  先给出数据结构
 

struct EDGE

{

int next;

int to;

int dist;

}mat[3*maxn];

int head[maxn];

next     这个.........不好表达,先说下面的
to 很显然,给出一条边,to就是边的终点
dist 就是这条边的权值
好的,还是说下我对next的理解吧
实际上是这样的,一般题目都会让你输入一堆边,那么这些边里免不了会有由同个起点引出的边,显然我们的边肯定是按输入顺序写在结构体里的,那么比如先输入了 1  5  7,意思是从1到5有一条边,长度是7 ,再输入 1  6  4,意思是从1到6有一条边,长度是4,这样的话,对于后一条边,他的mat[num].next就要指向离他最近的(前一个)有着同起点的边的下标,比如 mat[1].to=5.mat[1].dist=7,mat[1].next=-1  那么 mat[2].to=6,mat[2].dist=4,mat[2].next=1;
呼~~果然不是省油的灯,所谓的精华版邻接表
擦,还有个head数组没讲~~~~→→
head 数组,是用来指向最新的有着同起点的那条边的下标
比如前面的例子,那么起先全部初始化为-1(不是-1也可以,只要不会与你要用的重复就好了) ,head[1]先等于1,因为这是第一条边,也是最新的一条,但是接下来,head[1]要更新为2;

终于把这个解释好了
不过昨天有小伙伴问我,起点是怎么存的
我来说明下,head数组的下标就是你的起点,正因为有了这个数组,所以我们不需要关注起点,他可以飞快的帮我们找到
为了方便理解,我放点图上去

起点

终点

边权

1

3

7

2

3

6

1

4

5

3

5

1

2

7

11

4

5

7

3

4

6

2

4

5

1

2

7


下标

1

2

3

4

5

6

7

8

9

to

3

3

4

5

7

5

4

4

2

dist

7

6

5

1

11

7

6

5

7

next

-1

-1

1

-1

2

-1

4

5

3

下标

1

2

3

4

5

6

7

8

9

head

1->3->9

2->5->8

4->7

-1

-1

-1

-1

-1

-1

 实际上head只需要根据点的数量来选择数组的大小

一般mat数组的大小为head的3-4倍

哦~对了,那么上述过程如何实现呢,附上一小段代码
 
 

struct EDGE
{
int next;
int to;
int dist;
}mat[3*maxn];

int head[maxn];
int edgenum;

void addedge(int s,int t,int dis)
{
mat[edgenum].to=t;
mat[edgenum].dist=dis;
mat[edgenum].next=head[s]; //这条和下一条的代码千万不能反,否则就连不起来了
head[s]=edgenum++;
}

恩,我相信你们会懂的

~~~~~屌丝飘过