公元 2044 年,人类进入了宇宙纪元。
L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间,这 n?1 条航道连通了 L 国的所有星球。
小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰。
为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。
如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?
输入格式
第一行包括两个正整数 n,m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。
接下来 n?1 行描述航道的建设情况,其中第 i 行包含三个整数 ai,bi 和 ti,表示第 i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。数据保证 1≤ai,bi≤n 且 0≤ti≤1000。
接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。数据保证 1≤ui,vi≤n
输出格式
输出文件只包含一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。
样例一
input
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
output
11
思路:
这题在考场上,我一开始就看错了题目,以为是求扣去一条路让这些路的和最短,于是我就优先打了一遍树链剖分,然而输样例的时候,就有点不对了,我就有点慌了。
然后我细细观察题目发现了这道题是求让最大路最短的这样的问题,这样的问题让我联想到了二分,于是我在考场上就在原来树链剖分的情况下加了个二分(作死的开始,为什么?因为我打错了一些地方XD)。
二分答案值,然后用树链剖分把比答案大的路在树上覆盖,在线段树上找到让这些值合法且被所有路径覆盖的一条路,有则可以,无则不行,很明显可以推算出这是由单调性的,于是我毅然决然写了下去(时间太大,应该能90-95的样子)
95分代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 400000
struct xx{int l,r,len;
}d[N];
int fa[N],top[N],siz[N],size,son[N],pos[N],n,m,deep[N];
int L[N],R[N],qz[N],tou[N],dd,tree[N*4],tree1[N*4],tree2[N*4];
int sc[N],ans;
struct aa{int p,next;
}da[N*2];
void dfs(int x){for (int i=tou[x];i;i=da[i].next){int v=da[i].p;if (v!=fa[x]){fa[v]=x;deep[v]=deep[x]+1;dfs(v);siz[x]+=siz[v];if (siz[v]>siz[son[x]])son[x]=v;}}siz[x]+=1;
}
void dfs1(int x,int tp){pos[x]=++size;top[x]=tp;if (son[x])dfs1(son[x],tp);for (int i=tou[x];i;i=da[i].next){int v=da[i].p;if (v!=fa[x]&&v!=son[x])dfs1(v,v);}
}
void add(int x,int y){da[++dd].p=y;da[dd].next=tou[x];tou[x]=dd;
}
void clac(int x){tree[x]=tree[x*2]+tree[x*2+1];
}
void ins(int x,int l,int r,int xx,int xi,int v){if (l==r){tree[x]=v;return;}int mid=(l+r)/2;if (xx<=mid)ins(x*2,l,mid,xx,xi,v);if (mid<xx)ins(x*2+1,mid+1,r,xx,xi,v);clac(