AcWing 1128 信使

題目描述:

戰爭時期,前線有 n 個哨所,每個哨所可能會與其他若干個哨所之間有通信聯繫。

信使負責在哨所之間傳遞信息,當然,這是要花費一定時間的(以天爲單位)。

指揮部設在第一個哨所。

當指揮部下達一個命令後,指揮部就派出若干個信使向與指揮部相連的哨所送信。

當一個哨所接到信後,這個哨所內的信使們也以同樣的方式向其他哨所送信。信在一個哨所內停留的時間可以忽略不計

直至所有 n 個哨所全部接到命令後,送信纔算成功。

因爲準備充足,每個哨所內都安排了足夠的信使(如果一個哨所與其他 k 個哨所有通信聯繫的話,這個哨所內至少會配備 k 個信使)。

現在總指揮請你編一個程序,計算出完成整個送信過程最短需要多少時間。

輸入格式

第 1 行有兩個整數 n 和 m,中間用 1 個空格隔開,分別表示有 n 個哨所和 m 條通信線路。

第 2 至 m+1 行:每行三個整數 i、j、k,中間用 1 個空格隔開,表示第 i 個和第 j 個哨所之間存在 雙向 通信線路,且這條線路要花費 k 天。

輸出格式

一個整數,表示完成整個送信過程的最短時間。

如果不是所有的哨所都能收到信,就輸出-1。

數據範圍

1≤n≤100,
1≤m≤200,
1≤k≤1000

輸入樣例:

4 4
1 2 4
2 3 7
2 4 1
3 4 6

輸出樣例:

11

分析:

首先描述下題意,題目的意思就是從起點走到所有頂點,求走到所有頂點的耗時中時間最長的是哪個。也就是說只需要dijkstra算法跑一遍最短路,然後找出d中最大的即可。注意dijkstra算法中最後出隊的那個並不一定是距離最大的,只是該頂點是最後一個被更新而已,所以仍要對出隊的頂點取max。另外,只要存在不可達的頂點,就要輸出-1。

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int,int> PII;
const int N = 105,M = 405;
int d[N],n,m;
int idx,h[N],e[M],ne[M],w[M];
priority_queue<PII> pq;
bool st[N];
void add(int a,int b,int c){
    e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
}
int dijkstra(){
    memset(d,0x3f,sizeof d);
    memset(st,false,0);
    d[1] = 0;
    pq.push({-d[1],1});
    int ans = 0;
    while(pq.size()){
        int t = pq.top().second;
        ans = max(ans,d[t]);
        pq.pop();
        if(st[t])   continue;
        st[t] = true;
        for(int i = h[t];~i;i = ne[i]){
            int j = e[i];
            if(!st[j] && d[t] + w[i] < d[j]){
               d[j] = d[t] + w[i];//鬆弛操作 
               pq.push({-d[j],j});
            } 
        }
    }
    for(int i = 1;i <= n;i++){
        if(d[i] == 0x3f3f3f3f){
            ans = -1;
            break;
        }
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    int a,b,c;
    memset(h,-1,sizeof h);
    for(int i = 0;i < m;i++){
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c),add(b,a,c);
    }
    cout<<dijkstra()<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章