zoukankan      html  css  js  c++  java
  • 紧急救援 L2-001 dijkstra 打印路径 最短路条数 权值

    较为复杂的dijkstra 

    包含路径打印  最小路的条数  最小路径的情况下取最大权值

    v0要是标记就会出错。。。?

    有权值的题目  不能设置mp[i][i]为0  否则会无限加权

    这题很有参考价值 可以当模板

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    #define N 505
    #define inf 0x3f3f3f3f
    
    int path[N];//输出路径   存放的是i的前一个点  path[j]=u;
    int n,e,m,s;
    int vis[N],dis[N],mp[N][N];
    int city[N];//为权值   第一优先级为最短路  第二优先级为权值最或者最小 此为第二类权值(和点相连) 还有一种权值为和路相连 那种更简单
    int peo[N];
    int pathnum[N];//最短路的条数!!!   初始为1   只要在路径相同时累合即可
    
    void dijkstra(int s)
    {
        memset(vis,0,sizeof vis);
    
        for(int i=0;i<n;i++)
            dis[i]=mp[s][i];
        dis[s]=0;
    
        path[s]=-1;
        peo[s]=city[s];
        pathnum[s]=1;
        
        //明确规定不加vis[s]
    
        for(int i=1;i<=n;i++)
        {
            int minn=inf,u=-1;
            for(int j=0;j<n;j++)
                if(!vis[j]&&minn>dis[j])
                   minn=dis[u=j];
    
            if(u==-1)return;
            vis[u]=1;
    
            for(int j=0;j<n;j++)
            {
    
                if(dis[j]>dis[u]+mp[u][j])
                {
                   // pathnum[j]=pathnum[u];//最短路条数
                    dis[j]=dis[u]+mp[u][j];
                    path[j]=u;
                    peo[j]=peo[u]+city[j];
                }
                else if(dis[j]==dis[u]+mp[u][j])
                {
                   // pathnum[j]+=pathnum[u];//最短路条数
                    if(peo[j]<peo[u]+city[j])
                    {
                    path[j]=u;
                    peo[j]=peo[u]+city[j];
                    }
                }
            }
        }
    }
    
    void print(int x)
    {
       if(path[x]==-1)
        {printf("%d",x);return;}
       print(path[x]);
        printf(" %d",x);
        return ;
    }
    
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&s,&e);
        for(int i=0;i<n;i++)scanf("%d",&city[i]);
        
        for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
          mp[i][j]=inf;//如果加上 i==j 时mp为0  则可以反复刷权值
          
         while(m--)
         {
             int a,b,c;
             scanf("%d%d%d",&a,&b,&c);
             if(mp[a][b]>c)mp[a][b]=mp[b][a]=c;
         }
         dijkstra(s);
         printf("%d %d
    ", pathnum[e] ,peo[e] );
         print(e);
        return 0;
    }
  • 相关阅读:
    Mysql的表名/字段名/字段值是否区分大小写
    20个PHP程序性能优化的方法
    PHP中大括号用法
    PHP伪类型和伪变量
    PHP中关于取模运算及符号
    PHP之array_flip()方法
    PHP之implode()方法
    PHP中is_null()方法
    原型模式(Prototype)
    适配器模式
  • 原文地址:https://www.cnblogs.com/bxd123/p/10369166.html
Copyright © 2011-2022 走看看