AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 1127. 【算法提高课】香甜的黄油(Dijkstra)    原题链接    简单

作者: 作者的头像   incra ,  2022-11-17 14:16:43 ,  所有人可见 ,  阅读 2007


32


2

<—点个赞吧QwQ

宣传一下算法提高课整理

农夫John发现了做出全威斯康辛州最甜的黄油的方法:糖。

把糖放在一片牧场上,他知道 N 只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。

当然,他将付出额外的费用在奶牛上。

农夫John很狡猾,就像以前的巴甫洛夫,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。

他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。

农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。

给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。

数据保证至少存在一个牧场和所有牛所在的牧场连通。

输入格式

第一行: 三个数:奶牛数 N,牧场数 P,牧场间道路数 C。

第二行到第 N+1 行: 1 到 N 头奶牛所在的牧场号。

第 N+2 行到第 N+C+1 行:每行有三个数:相连的牧场A、B,两牧场间距 D,当然,连接是双向的。

输出格式

共一行,输出奶牛必须行走的最小的距离和。

数据范围

$1 \le N \le 500$,
$2 \le P \le 800$,
$1 \le C \le 1450$,
$1 \le D \le 255$

输入样例:

3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5

输出样例:

8

思路

我们枚举以当前点为起点,跑$\text{Dijkstra}$,如果有某一个点跑不到就直接返回正无穷,否则返回所有牛,的最短距离之和。

代码

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
typedef pair <int,int> PII;
const int N = 810,M = 3010,INF = 0x3f3f3f3f;
int n,p,m;
int cow[N];
int h[N],e[M],w[M],ne[M],idx;
bool st[N];
int dist[N];
void add (int a,int b,int c) {
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}
int dijkstra (int s) {
    memset (st,false,sizeof (st));
    memset (dist,0x3f,sizeof (dist));
    dist[s] = 0;
    priority_queue <PII,vector <PII>,greater <PII>> heap;
    heap.push ({0,s});
    while (!heap.empty ()) {
        int t = heap.top ().second;
        heap.pop ();
        if (st[t]) continue;
        st[t] = true;
        for (int i = h[t];~i;i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[t] + w[i]) {
                dist[j] = dist[t] + w[i];
                heap.push ({dist[j],j});
            }
        }
    }
    int ans = 0;
    for (int i = 1;i <= n;i++) {
        if (dist[cow[i]] == INF) return INF;
        ans += dist[cow[i]];
    }
    return ans;
}
int main () {
    memset (h,-1,sizeof (h));
    cin >> n >> p >> m;
    for (int i = 1;i <= n;i++) cin >> cow[i];
    while (m--) {
        int a,b,c;
        cin >> a >> b >> c;
        add (a,b,c);
        add (b,a,c);
    }
    int ans = INF;
    for (int i = 1;i <= p;i++) ans = min (ans,dijkstra (i));
    cout << ans << endl;
    return 0;
}

8 评论


用户头像
种花家的纽约市长   2023-01-28 21:21      2    踩      回复

Orz


用户头像
gsb   2023-10-25 20:45         踩      回复

基本和大佬一个代码,但是怎么一直在tle

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int,int> PII;
const int N=810,M=3010,INF = 0x3f3f3f3f;
int h[N],e[M],ne[M],w[N],idx;
int dist[N];
bool st[N];
int cow[N];
int n,m,p;

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

int dijkstra(int s)
{

    memset(dist,0x3f,sizeof (dist));
    memset(st,false,sizeof (st));
    dist[s]=0;

    priority_queue<PII,vector<PII>,greater<PII>> q;
    q.push({0,s});

    while(q.size())
    {
        int t=q.top().second;
        q.pop();

        if(st[t]) continue;
        st[t]=true;

        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                q.push({dist[j],j});
            }
        }
    }

    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(dist[cow[i]]==INF) return INF;
        ans+=dist[cow[i]];
    }
    return ans;
}

int main()
{
    memset(h,-1,sizeof h);

    cin>>n>>p>>m;
    for(int i=1;i<=n;i++) cin>>cow[i];
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }

    int ans=INF;
    for(int i=1;i<=p;i++) 
    {
        ans=min(ans,dijkstra(i));  
    }
    cout<<ans<<endl;
    return 0;
}
用户头像
philo1203   2023-11-06 20:04      3    踩      回复

好像是w数组的大小开错了,应该是要开成M。我也错过好几次这个。qwq

用户头像
user.banned   2023-12-26 14:44      3    踩      回复

双向剪边+链式前向星要开两倍空间

用户头像
gsb   2024-01-02 21:41    回复了 user.banned 的评论      1    踩      回复

谢谢,确实是这个问题,数组大小开小了


用户头像
吃饱了就来刷题   2023-10-24 20:49         踩      回复

想问一下add四条语句的意思是什么啊

用户头像
incra   2023-10-24 21:21         踩      回复

加边操作


用户头像
风清默   2023-07-06 14:26         踩      回复

tql


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息