1. 程式人生 > >【BZOJ1509】[NOI2003]逃學的小孩 直徑

【BZOJ1509】[NOI2003]逃學的小孩 直徑

spa ans while src mage input memset com har

【BZOJ1509】[NOI2003]逃學的小孩

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 3
1 2 1
2 3 1
3 4 1

Sample Output

4

題解:顯然A和B是直徑的兩端點吧~(自己瞎證一下,或者瞎yy一下就行)

然後枚舉C就做完了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=200010;
typedef long long ll;
int n,cnt,r1,r2,rt;
ll ans;
int to[maxn<<1],next[maxn<<1],head[maxn];
ll val[maxn<<1],dep[maxn<<1],f[maxn<<1];
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)	f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
inline void add(int a,int b,int c)
{
	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x,int fa)
{
	if(dep[x]>dep[rt])	rt=x;
	for(int i=head[x];i!=-1;i=next[i])	if(to[i]!=fa)	dep[to[i]]=dep[x]+val[i],dfs(to[i],x);
}
int main()
{
	n=rd(),rd();
	int i,a,b,c;
	memset(head,-1,sizeof(head));
	for(i=1;i<n;i++)	a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
	dfs(1,0),r1=rt;
	dep[r1]=0,dfs(r1,0),r2=rt,memcpy(f,dep,sizeof(dep));
	dep[r2]=0,dfs(r2,0);
	for(i=1;i<=n;i++)	ans=max(ans,dep[r1]+min(dep[i],f[i]));
	printf("%lld",ans);
	return 0;
}

【BZOJ1509】[NOI2003]逃學的小孩 直徑