记得存无向边的邻接表 好像有个名字来着...忘了
打习惯了上面那东西 现在感觉存单向的邻接表好难打
具体实现步骤见百度 那个马桶上看算法不错(名字怪怪的)
这里只放一下代码=-=因为找不到上面那家伙了 应该是被挤下去了
单向实现:
定义1 结构体 Edge {
int u,v,w;//u点 到 v点 有一条有向边连接 边权为 w
}edge[2333];
定义2 数组 int first[2333],next[2333];
前者 first[node] 意为 与 node 相连的 第一条遍历的 边 (网上大多都说要全赋初值为-1 其实不然)
后者 next[node] 意为 遍历完 第 node 条边后 应遍历哪条边 没有则为0 (同上括号则为-1)
Tip: 从零的话 判断只需 ! 就好 多省力~
代码: ( 读入 + 存储 边 )
for (int a = 1 ; a <= m ; a ++)//m为边数 如果后面用不到m 则循环1可为 while (m--)
{
scanf("%d%d%d",&edge[a].u,&edge[a].v,&edge[a].w);
next[a] = first[edge[a].u];
first[edge[a].u] = a;
}
双向实现:
定义1 结构体 Edge {
int to,next,w;
}edge[6666];//要开边数两倍 边权w存的话...应该不太标准
定义2 数组 int first[6666];//next在上面保存了 单向要在上面保存也可以 不过不太直观就是
定义3 int tot;//记录边数 然后在edge数组尾部添加边 充分利用空间 真是太美妙了OvO
void add(int x,int y,int w)
{
edge[++tot].v = w;
edge[tot].to = y;
edge[tot].next = first[x];
first[x] = tot;
}
int main()
{
scanf("%d%d",&n,&m);
for (int a = 1 ; a <= m ; a ++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
}
这里采用子程序 add 来实现 为什么呢 (居然还问为什么)
看主程序 (x,y) 和 (y,x) 很明显 这样子比较省力
当然 你如果要把单向的打两遍也没人说你 题目也过得了
鲁迅 : 体面给谁看呢~