我不黑博士
问题描述
在纠结了很久之后,博士终于决定约某个女生出来爬山(你们可以咨询我这个人的名字是什么,我可以免费告诉你哟,亲! ).
博士所在的城市特别奇怪,任何两个居住点之间有且仅有一条通路(其实这是方便博士遍历所有的路径来找后宫).
他决定先去接这个女生,然后再跟女生一起去爬山.
可是女生却不愿意告诉博士她到底在哪里(博士又被调戏了囧),她只是告诉了博士两个居住点,而她就在这两个居住点中的任意一个.
博士决定先去距离他所在的居住点近的一个居住点,如果女生不在这个居住点,他再去另外一个居住点接女生.
现在博士很好奇,如果不知道他所在的具体位置,也不知道女生告诉博士的两个居住点的具体位置,博士最坏情况下要走多远?
输入
输入文件名为 BlackBS.in。 (我不黑博士,对吧?)
输入第一行两个正整数
N
和
分别表示博士所在城市的楼房数和街道数。
下接
M
行,每行
输出
输出文件名为 BlackBS.out。
输出一行一个正整数,为最坏情况下博士要走的距离。
输入样例
4 3
1 2 1
2 3 1
3 4 1
输出样例
4
数据范围
对于
20%
的数据,
n<=100
;
m<=10000
; 每条街道的长度
<=100
<script type="math/tex" id="MathJax-Element-266"><=100</script>;
对于
100%
的数据,
n<=200000
;
m<=2000000
; 每条街道的长度
<=100000
<script type="math/tex" id="MathJax-Element-270"><=100000</script>.
Solution
求出树的直径,其两段即为女生的居住点;
然后枚举博士所在的位置,更新最大值即可。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define LL long long
using namespace std;
int n,m,l,r,cnt;
LL maxn;
int head[200010],nxt[4000010],data[4000010],flow[4000010];
LL dis[200010],dis2[200010];
bool in_stack[200010];
queue<int>q;
void add(int x,int y,int z){
nxt[cnt]=head[x];data[cnt]=y;flow[cnt]=z;head[x]=cnt++;
nxt[cnt]=head[y];data[cnt]=x;flow[cnt]=z;head[y]=cnt++;
}
void spfa(int s){
dis[s]=0;
in_stack[s]=true;
q.push(s);
while(!q.empty()){
int now=q.front();
q.pop();
in_stack[now]=false;
for(int i=head[now];i!=-1;i=nxt[i])
if(dis[data[i]]>dis[now]+flow[i]){
dis[data[i]]=dis[now]+flow[i];
if(!in_stack[data[i]]){
in_stack[data[i]]=true;
q.push(data[i]);
}
}
}
}
void spfa2(int s){
dis2[s]=0;
in_stack[s]=true;
q.push(s);
while(!q.empty()){
int now=q.front();
q.pop();
in_stack[now]=false;
for(int i=head[now];i!=-1;i=nxt[i])
if(dis2[data[i]]>dis2[now]+flow[i]){
dis2[data[i]]=dis2[now]+flow[i];
if(!in_stack[data[i]]){
in_stack[data[i]]=true;
q.push(data[i]);
}
}
}
}
int main(){
freopen("blackbs.in","r",stdin);
freopen("blackbs.out","w",stdout);
memset(head,-1,sizeof head);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
memset(dis,0x3f,sizeof dis);maxn=-dis[0];
spfa(1);
for(int i=1;i<=n;i++)
if(dis[i]>maxn){
maxn=dis[i];
l=i;
}
memset(dis,0x3f,sizeof dis);maxn=-dis[0];
spfa(l);
for(int i=1;i<=n;i++)
if(dis[i]>maxn){
maxn=dis[i];
r=i;
}
memset(dis2,0x3f,sizeof dis2);maxn=-dis2[0];
spfa2(r);
for(int i=1;i<=n;i++)
maxn=Max(maxn,Min(dis2[i],dis[i]));
printf("%lld\n",maxn+dis[r]);
return 0;
}