1. 程式人生 > >BZOJ1509 NOI2003 逃學的小孩

BZOJ1509 NOI2003 逃學的小孩

tdi eve col image () AD i++ zoj script

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。

思路:由於規則2,可知題目給出的是一棵樹

然後求一根直徑,兩個家就在直徑兩端

兩端各遍歷一發,就可以知道每個點到兩端的距離,然後取出每個點到兩端的最小距離再加上直徑長度即可

技術分享圖片
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 1e6 + 10;
 
int head[N], now;
struct edges{
    int to, next, w;
}edge[N<<1];
void add(int u, int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}
 
long long n, m, d[N], l, r, f[N]; int bfs(int x){ queue<int> q; memset(d, 0x3f, sizeof(d)); q.push(x); d[x] = 0; while(!q.empty()){ int x = q.front(); q.pop(); for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(d[v] > d[x] + edge[i].w){ d[v]
= d[x] + edge[i].w; q.push(v); } } } for(int i = 1; i <= n; i++) if(d[i] > d[x]) x = i; return x; } int main(){ scanf("%lld%lld",&n, &m); int x, y, z; for(int i = 1; i <= m; i++){ scanf("%d%d%d",&x, &y, &z); add(x, y, z); add(y, x, z); } l = bfs(1); r = bfs(l); memcpy(f, d, sizeof(d)); bfs(r); long long mx = 0; for(int i = 1; i <= n; i++) mx = max(mx, min(d[i], f[i])+ f[r]); printf("%lld\n", mx); return 0; }
View Code

BZOJ1509 NOI2003 逃學的小孩