邻接表
第一行两个数n,m。n表示顶点个数(编号1~n),m为边的条数。接下来m行,每行三个x y z。表示顶点x到顶点y的边的权值为z。
用邻接表存储这个图:
int n,m,i; //u,v,w的数组大小要根据实际情况来设置,要比m的最大值大1 int u[6],v[6],w[6]; //first和next的数组大小要根据实际情况来设置,first比n要大1,next要比m的最大值要大1; int first[5,]next[6]; scanf("%d %d",&n,&m); for(i=1;i<=n;i++) first[i]=-1;//初始化first数组下标1~n的值为-1,表示1~n顶点暂时都没边 for(i=1;i<=m;i++) { scanf("%d %d %d",&u[i],&v[i],w[i]);//读入每一条边 //下面两句关键句 next[i]=first[u[i]]; first[u[i]]=i; }
first[u[i]]就是保存顶点u[i]的第一条边,next[i]存储“编号为i的边”的“下一条边”的编号。


如上图,1号顶点的边是编号为5的边 (1,3,7),2号..(2,4,6).......遍历1号顶点的每一条边如下图:
k=first[1]; while(k!=-1) { printf("%d %d %d\n",u[k],v[k],w[k]); k=next[k]; }
输出顺序和原来读入的时候相反,因为每个顶点插入边的时候都会插入“链表”的首部而不是尾部
遍历每个顶点的边如下:

找到1号顶点的一条边后,剩下的边都可以在next找到。
for(i=1;i<=n;i++) { k=first[i]; while(k!=-1) { printf("%d %d %d\n",u[k],v[k],w[k]); k=next[k]; } }
这个算法不能求最短路径带有负权边

浙公网安备 33010602011771号