[BZOJ1509][NOI2003]逃學的小孩
阿新 • • 發佈:2018-08-02
div 最壞情況 size git print src alt isa ron
1 2 1
2 3 1
3 4 1
Description
Input
第一行是兩個整數N(3 ? N ? 200000)和M,分別表示居住點總數和街道總數。以下M行,每行給出一條街道的信息。第i+1行包含整數Ui、Vi、Ti(1?Ui, Vi ? N,1 ? Ti ? 1000000000),表示街道i連接居住點Ui和Vi,並且經過街道i需花費Ti分鐘。街道信息不會重復給出。Output
僅包含整數T,即最壞情況下Chris的父母需要花費T分鐘才能找到Chris。Sample Input
4 31 2 1
2 3 1
3 4 1
Sample Output
4
肯定會選樹的直徑,然後其他點枚舉一下,取到直徑兩端距離的最小值的最大值,然後加上樹的直徑就是答案。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; #define int long long #define g getchar() #define i isdigit(ch) inline int read(){ int res=0;char ch=g; while(!i) ch=g;while(i) {res=(res<<3)+(res<<1)+(ch^48);ch=g;} return res; } #undef g #undef i #define N 200005 int n, m; struct edge{ int nxt, to, val; }ed[N*2]; int head[N], cnt; inline void add(int x, int y, int z) { ed[++cnt] = (edge){head[x], y, z}; head[x] = cnt; } intdis[N], disa[N], disb[N]; int p1, p2; int ans1, ans2; bool ex[N]; void dfs(int x) { ex[x] = 1; for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if (ex[to]) continue; dis[to] = dis[x] + ed[i].val; dfs(to); } } inline void SPFA1(int cur) { memset(ex, 0, sizeof ex); memset(disa, 0x3f, sizeof disa); disa[cur] = 0; queue <int> q; q.push(cur); while(!q.empty()) { int x = q.front();q.pop(); ex[x] = 0; for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if (disa[to] > disa[x] + ed[i].val) { disa[to] = disa[x] + ed[i].val; if (!ex[to]) { ex[to] = 1; q.push(to); } } } } } inline void SPFA2(int cur) { memset(ex, 0, sizeof ex); memset(disb ,0x3f, sizeof disb); disb[cur] = 0; queue <int> q; q.push(cur); while(!q.empty()) { int x = q.front();q.pop(); ex[x] = 0; for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if (disb[to] > disb[x] + ed[i].val) { disb[to] = disb[x] + ed[i].val; if (!ex[to]) { ex[to] = 1; q.push(to); } } } } } signed main() { n = read(),m = read(); for (int i = 1 ; i <= m ; i ++) { int x = read(), y = read(), z = read(); add(x, y, z), add(y, x, z); } dfs(1); p1 = 1; for (int i = 1 ; i <= n ; i ++) if (dis[i] > dis[p1]) p1 = i; memset(dis, 0, sizeof dis); memset(ex, 0, sizeof ex); dfs(p1); p2 = 1; for (int i = 1 ; i <= n ; i ++) if (dis[i] > dis[p2]) p2 = i; SPFA1(p1); SPFA2(p2); ans1 = disa[p2]; for (int i = 1 ; i <= n ; i ++) ans2 = max(ans2, min(disa[i], disb[i])); printf("%lld\n", ans1 + ans2); return 0; }
[BZOJ1509][NOI2003]逃學的小孩