201703-4 ccf 地鐵修建 (dijstra的靈活運用)
阿新 • • 發佈:2018-11-12
題目連結:
地鐵修建
題目大意:
中文題,不解釋啊啊!!!
解題思路:
題目要求使得完工時間最短,因為可以同時開工,所以抽象出來就是。從1到n的多條路線中,選一條路徑所經過的邊中最大的邊權最小(看樣例就可以理解這句話了)。
於是我們可以利用求最短路的法子來求這個最大邊權最小。之前求最短路是記錄1到當前節點的最短路,那我是不是可以改變一下鬆弛條件,dist[i]記錄的是1節點到當前節點i所有路徑中最大變權的最小值呢,然後每次往後鬆弛,比較一下dist[u]和當前邊權的大小,選大的和dist[v]去比,不斷更新dist[v],最後就可以得到最優解了!!!
AC程式碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 1e5+7;
int n,m;
int vis[MAXN],dist[MAXN];
struct node{
int v;
int c;
node(int _v, int _c):v(_v),c(_c){}
bool operator <(const node&a)const{
return c > a.c;
}
};
vector<node> g[MAXN];
void dijstra(){
priority_queue<node> pq;
pq.push(node(1,0));
dist[1] =0;
while(!pq.empty()){
node tmp = pq.top();
pq.pop();
int u = tmp.v;
if(vis[u]) continue ;
vis[u] = 1;
for(int i=0; i<g[u].size(); ++i){
int v = g[u][i].v;
int cost = g[u][i].c;
if(max(cost, dist[u]) < dist[v]){
dist[v] = max(cost, dist[u]);
pq.push(node(v,dist[v]));
}
}
}
}
void init(){
for(int i=0; i<MAXN; ++i) g[i].clear();
memset(vis, 0, sizeof(vis));
for(int i=0; i<MAXN; ++i) dist[i] = 0x3f3f3f3f;
}
int main(){
init();
cin>>n>>m;
for(int i=0; i<m; ++i){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
g[u].push_back(node(v,c));
g[v].push_back(node(u,c));
}
dijstra();
cout<<dist[n]<<endl;
return 0;
}