題目描述:
戰爭時期,前線有 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;
}