1. 程式人生 > >201703-4 ccf 地鐵修建 (dijstra的靈活運用)

201703-4 ccf 地鐵修建 (dijstra的靈活運用)

題目連結:
地鐵修建

題目大意:
中文題,不解釋啊啊!!!

解題思路:
題目要求使得完工時間最短,因為可以同時開工,所以抽象出來就是。從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; }