个人见解,如有错误,欢迎指出。
作为一个算法新手,我就从我个人的角度来讲述前向星这种算法,我看到大多数都是建立一个边集的结构体,然后在结构体内放入边指向结点,边的前驱,和边权:
例如:
struct edge{//建立一个边集结构体
int next;//好一点的把next换成了pre,从字面上来讲更好理解
int w;//边的权值
int v;//边指向结点,有的写成to
}e[maxn];
当然对于一个已经懂得了前向星的人来讲,这种写法也还是比较好理解的。下面进入主题:
同样的我们还是建立一个结构体,但是,我们把名字改成graph,没错,就是graph。表明我们是对一个图进行操作。
由于前向星是一种反向遍历的方式,我们把相应的next和v改成front和to,这样从字面生更好理解。我们按输入顺序对每条边赋予一个值,表明是第几条输入边(也就是说每条边都有一个独一无二的IP地址了)
即:使用链表方式存储图的边。last[i]用来记录以i为起点且为最后输入的一条边,front[j] 表示边j的前一条边(这里的前一条边不仅仅是指输入顺序在j的前面,而且还得和j拥
有相同的起点),to[j]表示第j条边所指向的结点编号。即:令addr=last[i],之后不断用 addr=front[addr]即可得到链表中所有以结点i为起点的所有“边集的编号”,其中
to[addr]表示对应边指向的结点编号。那么这样做有什么用呢?比如我们想知道有没有一条从u到v的边,我们只需要这样遍历所有从u出发的边,看有无终点是v即可。
代码:
#define Add(u,v,w) {E[++tot]=(Edge){u,v,w,Last[u]}; Last[u]=tot;}
struct Edge{
int u,v,w,Front;
}E[maxm]; int tot,Last[maxn];
int main(){
memset(Last,-1,sizeof(Last)); tot=0;
int u,v,w;
while(cin>>u>>v>>w){
Add(u,v,w); Add(v,u,w);
}
return 0;
}
好了我的讲述就到这里了吧,个人认为这种写法还是比较好理解的,代码嘛也不是很长。