• 链式前向星


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=1e4+5;
    int head[N];//链式地址
    int cnt=0;//边的下标
    struct node{
        int from;//表示与第cnt条边同起点的上一条边的储存位置
        int to;
        int w;
    }edge[N];
    void add(int u,int v,int w){
        edge[cnt].w=w;//第cnt条边的权值是w
        edge[cnt].to=v;//第cnt条边的终点是v
        edge[cnt].from=head[u];//head[i]表示以i起点的最后一条边的储存位置
        head[u]=cnt++;//head[];
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        memset(head,0,sizeof(head));
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        int start;
        scanf("%d",&start);
        for(int i=head[start];i!=0;i=edge[i].from){//输出某个指定结点的连接情况
            cout<<start<<"->"<<edge[i].to<<" "<<edge[i].w<<endl;
        }
        return 0;
    }

     邻接表

    void add(int x,int y,int z){
        ver[tot++]=y;//ver存储的每条边终点 
        edge[tot]=z;//边权 
        next[tot]=head[x];// 
        head[x]=tot;//head理解从x出发的一个集合 可以根据它找所有边 
    } 
    head
     1   --head[1]=1--> ver[1]=2-->next[1]=0;
     2   --head[2]=3--> ver[3]=5-->ver[2]=3-->next[2]=0;
     3   --head[3]=4--> ver[4]=5-->next[4]=0;
     4   --head[4]=0-->;
     5   --head[5]=6--> ver[6]=1-->next[6]=5-->ver[5]=4-->next[5]=0;
     插入(1,2),(2,3),(2,5),(3,5),(5,4),(51for(int i=head[x];i;i=next[i]){
         int y=ver[i],z=edge[i];
         //找出了一条(x,y)有向边,权值为c 
     } 
     ver[i]是i条边的终点,ver[1 xor i]为i起点 
    //SPFA 
    #include<cstdio> 
    using namespace std; 
    int dis[500010],n,m,f,g,w,t=1,s,q[200000],h,st[500010],tot;
    bool vis[100010];
    /*
    st[i]表示到达i点的最后一条边的编号; 
    dis[i]表示从起点到i点目前为止的最短距离; 
    vis[i]=true表示点i在队列里; 
    vis[i]=false表示点i不在队列里; 
    数组q是队列; 
    h是指队列的头指针,t是指队列的尾指针; 
    */
    struct node //不开结构体,变量有点乱,所以开结构体; 
    { 
        int to;//这条边连接的终点; 
        int v;//这条边的长度; 
        int last;//前一条边; 
    }e[500010]; 
    void add(int from,int to,int val)
    /*
    val表示传入的这条边的权值; 
    from表示传入的这条边的起点; 
    to表示传入的这条边的终点; 
    */
    {     
        tot++;//表示当前这条边的编号; 
        e[tot].to=to;//更新当前这条边的终点; 
        e[tot].v=val;//更新当前这条边的长度(权); 
        e[tot].last=st[from];
    /*
        e[tot].last表示的是当前读入的这条边的上一条边; 
        st[from]表示的是 到当前读入的边为止(不包括这条边) 的上一条边的序号; 
    */
        st[from]=tot;//更新为 当前读入的边为止(包括这条边) 的上一条边的序号;
    } 
    void SPFA()//核心最短路;
    {
        while(h<=t)//队列不为空; 
        {
            h++; 
            int u=q[h];//取出队首
            vis[u]=0;//队首出队
            for(int i=st[u]; i!=0; i=e[i].last)
    /*
    st[u]是指可以到达点u的上一条边,如果存在st[u](也就是st[u]不为0,因为0是初始值),
    说明有一条边可以到达点u。所以i变成st[u]。e[i].last是指可以到达st[u]这条边的起点的边的编号
    */
            {
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].v)
    /*
    如果从起点到v的距离大于从起点到点i,再从点i到点u,再从点u到点v的距离,更新从起点
    到点v的最短路; 
    */
                {
                    dis[v]=dis[u]+e[i].v;
                    if(vis[v]==0)//没有入过队就入队; 
                    {
                        vis[v]=1;//标志改为1,表示已经入队; 
                        t++;
                        q[t]=v; 
                    }
                }
            }
        } 
    }  
    int main() //主程序; 
    {  
        scanf("%d %d %d",&n,&m,&s); 
        for(int i=1;i<=m;i++) 
        { 
            scanf("%d %d %d",&f,&g,&w);//输入这条边的起点f,终点g和长度w;  
            add(f,g,w);//建图;
        } 
        for(int i=1;i<=n;i++)//因为题目要我们求一个点到其余点的最短路; 
            dis[i]=2147483647;//所以初始化全部赋为int的最大值; 
        dis[s]=0;//起点到本身的的距离为0;
        q[t]=s;//起点入队; 
        vis[s]=true;//标志改为true表示起点已入队; 
        SPFA(); //运行最短路; 
        for(int i=1;i<=n;i++)//循环输出答案; 
            printf("%d ",dis[i]);
        return 0; 
    }

     

  • 相关阅读:
    阅读提问
    阅读笔记
    结对需求分析
    分工
    对软件工程课程的期望
    JAVAWEB-Spring Boot学习
    团队编程-项目作业6-程序维护
    团队-吃货之家-项目总结
    团队编程项目作业5-小组评分
    安装Vue.js之Node.js,NMP环境搭建
  • 原文地址:https://www.cnblogs.com/shikeyu/p/12828257.html
Copyright © 2020-2023  润新知