• AcWing 1127. 香甜的黄油 spfa


    地址 https://www.acwing.com/solution/content/15728/

    农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖。
    
    把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。
    
    当然,他将付出额外的费用在奶牛上。
    
    农夫John很狡猾,就像以前的巴甫洛夫,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。
    
    他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。
    
    农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。
    
    给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。
    
    数据保证至少存在一个牧场和所有牛所在的牧场连通。
    输入格式
    
    第一行: 三个数:奶牛数 N,牧场数 P,牧场间道路数 C。
    
    第二行到第 N+1 行: 1 到 N 头奶牛所在的牧场号。
    
    第 N+2 行到第 N+C+1 行:每行有三个数:相连的牧场A、B,两牧场间距 D,当然,连接是双向的。
    输出格式
    
    共一行,输出奶牛必须行走的最小的距离和。
    数据范围
    
    1≤N≤500
    ,
    2≤P≤800,
    1≤C≤1450,
    1≤D≤255
    
    样例
    输入样例:
    
    3 4 5
    2
    3
    4
    1 2 1
    1 3 5
    2 3 7
    2 4 3
    3 4 5
    
    输出样例:
    
    8

    解答

    算法1
    我们需要
    一个比较快的图最短路算法,
    尝试以每个农场作为放置糖的位置,牛坐过去的最短路径和
    这里使用spfa

    C++ 代码

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    /*
    输入样例:
    3 4 5
    2
    3
    4
    1 2 1
    1 3 5
    2 3 7
    2 4 3
    3 4 5
    输出样例:
    8
    */
    
    int n, p,c;
    const int N = 510;
    const int P = 810;
    const int C = 1510;
    
    
    int Point[N];
    
    const int INF = 0x3f3f3f3f;
    
    int dist[P];
    bool st[P];
    vector<pair<int, int>> g[P];
    
    
    int spfa(int x)
    {
        memset(dist, 0x3f, sizeof dist);
        memset(st, 0, sizeof st);
    
        dist[x] = 0;
    
        queue<int>q;
        q.push(x);
        st[x] = true;
    
        while (q.size()) {
            int t = q.front();
            q.pop();
    
            st[t] = false;
    
            for (int i = 0; i < g[t].size(); i++) {
                int j = g[t][i].first;
                int w = g[t][i].second;
    
                if (dist[j] > dist[t] + w) {
                    dist[j] = dist[t] + w;
                    if (!st[j]) {
                        q.push(j);
                        st[j] = true;
                    }
                }
            }
        }
    
        int sum = 0;
    
        for (int i = 0; i < n; i++) {
            if(dist[Point[i]] == INF) return INF;
            sum += dist[Point[i]];
        }
    
        return sum;
    }
    
    
    
    int main()
    {
        cin >> n >> p >> c;
        for (int i = 0; i < n; i++) {
            cin >> Point[i];
        }
    
        for (int i = 0; i < c; i++) {
            int a, b, c;
            cin >> a >> b >> c;
            g[a].push_back({ b,c });
            g[b].push_back({ a,c });
        }
    
        int ans = 99999999;
        for (int i = 1; i <= p; i++) {
            ans = min(ans, spfa(i));
        }
    
        cout << ans << endl;
    
        return 0;
    }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Linux Sever简单笔记(第十二堂课)之linux下的系统故障分析和排查
    Linux Sever简单笔记(第十一堂课)之linux下的备份和恢复及rsync还有inotify和dump以及restore
    Linux Sever简单笔记(第十堂课)之linux下的任务计划及相关的命令
    ubuntu18.04设置apt源(国内)
    shell简单常用脚本实例
    装完ubuntu系统之后,不能ssh正常连接
    mysql主从复制以及读写分离
    复习计划
    linux下dhcp的安装及配置
    日常问题
  • 原文地址:https://www.cnblogs.com/itdef/p/13245710.html
Copyright © 2020-2023  润新知