描述
Chris 家的电话铃响起了,里面传出了 Chris 的老师焦急的声音:“喂,是 Chris 的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris 的父母就心急如焚,他们决定在尽量短的时间内找到 Chris。他们告诉 Chris 的老师:“根据以往的经验,Chris 现在必然躲在朋友 Shermie 或 Yashiro 家里偷玩《拳皇》游戏。现在,我们就从家出发去找 Chris,一旦找到,我们立刻给您打电话。”说完砰的一声把电话挂了。
Chris 居住的城市由 N 个居住点和若干条连接居住点的双向街道组成,经过街道 x 需花费 Tx 分钟。可以保证,任两个居住点间有且仅有一条通路。Chris 家在点 C,Shermie 和 Yashiro 分别住在点 A 和点 B。Chris 的老师和 Chris 的父母都有城市地图,但 Chris 的父母知道点 A、B、C 的具体位置而 Chris 的老师不知。
为了尽快找到 Chris,Chris 的父母会遵守以下两条规则:
- 如果 A 距离 C 比 B 距离 C 近,那么 Chris 的父母先去 Shermie 家寻找 Chris,如果找不到,Chris 的父母再去 Yashiro 家;反之亦然。
- Chris 的父母总沿着两点间唯一的通路行走。
显然,Chris 的老师知道 Chris 的父母在寻找 Chris 的过程中会遵守以上两条规则,但由于他并不知道 A、B、C 的具体位置,所以现在他希望你告诉他,最坏情况下 Chris的父母要耗费多长时间才能找到 Chris?
例如上图,这座城市由 4 个居住点和 3 条街道组成,经过每条街道均需花费1 分钟时间。假设 Chris 住在点 C,Shermie 住在点 A,Yashiro 住在点 B,因为 C 到 B 的距离小于 C 到 A 的距离,所以 Chiris 的父母会先去 Yashiro 家寻找 Chris,
一旦找不到,再去 Shermie 家寻找。这样,最坏情况下 Chris 的父母需要花费 4 分钟的时间才能找到 Chris。
输入描述
输入文件第一行是两个整数 N 和 M,分别表示居住点总数和街道总数。
以下 M 行,每行给出一条街道的信息。第 i+1 行包含整数 Ui、Vi、Ti,表示街道 i 连接居住点 Ui 和 Vi,并且经过街道 i 需花费 Ti 分钟。街道信息不会重复给出。
输出描述
输出文件仅包含整数 T,即最坏情况下 Chris 的父母需要花费 T 分钟才能找到 Chris。
样例输入
4 3 1 2 1 2 3 1 3 4 1
样例输出
4
数据范围与提示
对于 100% 的数据,3≤N≤2×105,1≤Ui,Vi≤N,1≤Ti≤109。
代码如下:
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
ll read(){
ll x = 0; int zf = 1; char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
}
struct Edge{
int to, next;
ll dis;
} edges[400005];
int head[200005], edge_num;
void addEdge(int u, int v, ll w){
edges[++edge_num] = {v, head[u], w};
head[u] = edge_num;
}
ll dis[200005];
ll dis2[200005][2];
void getDis(int u, int fa, ll vl){
int v; dis[u] = ((u == fa) ? 0 : dis[fa] + vl);
for (int c_e = head[u]; c_e; c_e = edges[c_e].next){
v = edges[c_e].to; if (v == fa) continue;
getDis(v, u, edges[c_e].dis);
}
}
void getDis2(int u, int fa, ll vl, int op){
int v; dis2[u][op] = ((u == fa) ? 0 : dis2[fa][op] + vl);
for (int c_e = head[u]; c_e; c_e = edges[c_e].next){
v = edges[c_e].to; if (v == fa) continue;
getDis2(v, u, edges[c_e].dis, op);
}
}
int main(){
int n = read(), m = read();
for (int i = 1; i <= m; ++i){
int u = read(), v = read(); ll w = read();
addEdge(u, v, w), addEdge(v, u, w);
}
getDis(1, 1, 0);
int pos1; ll _max = -1;
for (int i = 1; i <= n; ++i)
if (dis[i] > _max)
_max = dis[i], pos1 = i;
getDis(pos1, pos1, 0);
int pos2; _max = -1;
for (int i = 1; i <= n; ++i)
if (dis[i] > _max)
_max = dis[i], pos2 = i;
getDis2(pos1, pos1, 0, 0);
getDis2(pos2, pos2, 0, 1);
ll _max2 = -1;
for (int i = 1; i <= n; ++i)
_max2 = max(_max2, ((dis2[i][0] > dis2[i][1]) ? dis2[i][1] : dis2[i][0]));
printf("%lld", _max + _max2);
return 0;
}