AcWing 1129. 热浪

题目传送门

题目描述

题目描述
德克萨斯纯朴的民众们这个夏天正在遭受巨大的热浪!!!

他们的德克萨斯长角牛吃起来不错,可是它们并不是很擅长生产富含奶油的乳制品。

农夫John此时身先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任,以减轻德克萨斯人忍受酷暑的痛苦。

John已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。

这些路线包括起始点和终点一共有 T 个城镇,为了方便标号为 1 到 T。

除了起点和终点外的每个城镇都由 双向道路 连向至少两个其它的城镇。

每条道路有一个通过费用(包括油费,过路费等等)。

给定一个地图,包含 C 条直接连接 2 个城镇的道路。

每条道路由道路的起点 Rs,终点 Re 和花费 Ci 组成。

求从起始的城镇 Ts 到终点的城镇 Te 最小的总费用。

输入格式
第一行: 4 个由空格隔开的整数: T,C,Ts,Te;

第 2 到第 C+1 行: 第 i+1 行描述第 i 条道路,包含 3 个由空格隔开的整数: Rs,Re,Ci。

输出格式
一个单独的整数表示从 Ts 到 Te 的最小总费用。

数据保证至少存在一条道路。

数据范围
1≤T≤2500,
1≤C≤6200,
1≤Ts,Te,Rs,Re≤T,
1≤Ci≤1000

输入样例
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
输出样例
7

Dijkstra求单源最短路

分析

注意题目说的是无向图,需要双向建边

这里使用的是优先队列优化的dijkstra,也可以使用spfa、朴素版dijkstra

代码

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

typedef pair<int, int> PII;
const int N = 2510;
const int INF = 0x3f3f3f3f;

int dist[N];
bool st[N]; 
int t, c;
int start, ed;

struct VER
{
    int to;
    int w;
};

vector<VER> h[N];

void add(int a, int b, int w)
{
    VER ver;
    ver.to = b;
    ver.w = w;
    h[a].push_back(ver);
}

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[start] = 0;
    
    priority_queue<PII, vector<PII>, greater<PII> > heap;
    heap.push({0, start});
    
    while(!heap.empty())
    {
        PII tmp = heap.top();
        heap.pop();
        
        int distance = tmp.first, ver = tmp.second;
        // distance 表示源点到ver点的最短距离
        
        if(st[ver]) continue; // 
        
        for(int i = 0; i < h[ver].size(); i++)
        {
            int j = h[ver][i].to, w = h[ver][i].w;
            
            if(!st[j] && dist[j] > distance + w)
            {
                dist[j] = distance + w;
                heap.push({dist[j], j});
            }
        }
        st[ver] = true;
    }
    
    if(dist[ed] == INF) return -1;
    else                return dist[ed];
}

int main()
{
    scanf("%d%d%d%d", &t, &c, &start, &ed);
    while(c --)
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        add(a, b, w);
        add(b, a, w);  // 注意是无向图,双向建边 
    }
    
    int res = dijkstra();
    
    printf("%d\n", res);
    return 0;
}


时间复杂度

参考文章

https://www.acwing.com/solution/content/16555/

posted @ 2022-03-06 09:32  VanHope  阅读(22)  评论(0编辑  收藏  举报