• Aizu


    题目:给出若干个建筑之间的一些路,每条路都有对应的长度和需要的花费,问在保证源点1到其他个点的距离最短的情况下,最少的花费是多少/

    思路:和一般的最短路问题相比,多了一个 数组id【i】,用来记录到达i点在距离最短的情况下是由那条边到达的。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<queue>
    #include<string>
    #include<algorithm>
    #define MAXSIZE 1000005
    #define LL long long
    #define INF 0x3f3f3f3f
    using namespace std;
    
    //给出若干个建筑之间的一些路,每条路都有对应的长度和需要的花费,
    //问在保证源点1 到其他个点的距离最短的情况下,最少的花费是多少
    
    int n,m,vis[MAXSIZE],a[MAXSIZE],k,dist[MAXSIZE],id[MAXSIZE];
    
    struct node
    {
        int u;
        int v;
        int w;
        int c;
        int next;
    }G[MAXSIZE];
    
    void Add(int u,int v,int w,int c)
    {
        G[k].u = u;
        G[k].v = v;
        G[k].w = w;
        G[k].c = c;
        G[k].next = a[u];
        a[u] = k++;
    }
    
    int dij()
    {
        memset(vis,0,sizeof(vis));
        memset(id,-1,sizeof(id));
        dist[1] = 0;
        int minn ,p;
        for(int i=1;i<k;i++)
        {
            minn = INF;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j] && dist[j] < minn)
                {
                    minn = dist[j];
                    p = j;
                }
            }
    
            if(minn == INF)
                break;
            vis[p] = 1;
            for(int j=a[p];j!=-1;j=G[j].next)
            {
                int v = G[j].v;
                if(dist[v] > dist[p] + G[j].w && !vis[v]) //距离更短就更新
                {
                    dist[v] = dist[p] + G[j].w;
                    id[v] = j;
                }
                
                //距离相同,花费更小就更新
                else if(id[v]!=-1 && dist[v] == dist[p] + G[j].w && G[j].c < G[id[v]].c && !vis[v])
                {
                    id[v] = j;
                }
            }
        }
    
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            if(id[i] == -1)
                continue;
            else
                sum += G[id[i]].c;
        }
        return sum;
    }
    
    void Init()
    {
        memset(a,-1,sizeof(a));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<MAXSIZE;i++)
            dist[i] = INF;
        k = 1;
    }
    
    int main()
    {
        int u,v,w,c;
        while(scanf("%d%d",&n,&m),n+m)
        {
            Init();
    
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d%d",&u,&v,&w,&c);
                Add(u,v,w,c);
                Add(v,u,w,c);
            }
    
            int ans = dij();
    
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    我心里优秀架构师是怎样的?
    Rock Pi开发笔记(一):Rock Pi系列arm产品方案快速落地方案介绍
    面试官:Redis中有序集合的内部实现方式是什么?
    面试官:Java中对象都存放在堆中吗?你知道逃逸分析?
    多线程设计模式之保护性暂停
    多线程之深入理解park与unpark
    模拟实现FutureTask
    多线程之park()与interrupt()的理解
    多线程之活锁(了解一下就可以了)
    多线程之模拟自定义消息队列
  • 原文地址:https://www.cnblogs.com/alan-W/p/7266324.html
Copyright © 2020-2023  润新知