邻接表

第一行两个数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];
     } 
}

这个算法不能求最短路径带有负权边

posted @ 2020-04-21 22:34  一只菜鸡!  阅读(156)  评论(0)    收藏  举报