Description
公元2044年,人类进入了宇宙纪元。
国有个星球,还有条双向航道,每条航道建立在两个星球之间,这条航道连通了国的所有星球。
小掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从号星球沿最快的宇航路径飞行到号星球去。显然,飞船驶过一条航道是需要时间的,对于航道,任意飞船驶过它所花费的时间为,并且任意两艘飞船之间不会产生任何干扰。
为了鼓励科技创新,国国王同意小的物流公司参与国的航道建设,即允许小把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。在虫洞的建设完成前小的物流公司就预接了个运输计划。在虫洞建设完成后,这个运输计划会同时开始,所有飞船一起出发。当这个运输计划都完成时,小的物流公司的阶段性工作就完成了。如果小可以自由选择将哪一条航道改造成虫洞,试求出小的物流公司完成阶段性工作所需要的最短时间是多少?
Input
第一行包括两个正整数,表示国中星球的数量及小公司预接的运输计划的数量,星球从1到编号。接下来行描述航道的建设情况,其中第行包含三个整数 和,表示第条双向航道修建在与两个星球之间,任意飞船驶过它所花费的时间为。数据保证 。接下来行描述运输计划的情况,其中第行包含两个正整数和,表示第个运输计划是从号星球飞往号星球。
Output
输出文件只包含一个整数,表示小的物流公司完成阶段性工作所需要的最短时间。
Sample Input
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
Sample Output
11
HINT
Solution
这道题就是求在一条边的时间不算的情况下,求到的最大值的最小值.
显然二分答案,然后判断对于所有花费时间的的交是否为空.
如果不为空,若
属于所有花费时间的的交,则合法.
求路径交是否为空=求是否存在一条边所有路径都经过.
表示连向它父亲的那条边有多少条路径经过,
每次,向上传递即可.
#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define K 20 #define N 300005 #define M 600005 #define INF 300000000 using namespace std; typedef long long ll; struct graph{ int nxt,to,w; }e[M]; struct line{ int l,r,f,w; }a[N]; int f[N][K],g[N],t[N],w[N],ef[N],dep[N],n,m,mk,sum,cnt; bool v[N],flag; stack<int> s; inline int read(){ int ret=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ ret=(ret<<1)+(ret<<3)+c-'0'; c=getchar(); } return ret; } inline void addedge(int x,int y,int w){ e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;e[cnt].w=w; } inline void dfs(int u){ dep[u]=1;s.push(u); while(!s.empty()){ u=s.top();s.pop(); if(u==1) for(int i=0;i<K;++i) f[u][i]=1; else for(int i=1;i<K;++i) f[u][i]=f[f[u][i-1]][i-1]; for(int i=g[u];i;i=e[i].nxt) if(!dep[e[i].to]){ s.push(e[i].to); f[e[i].to][0]=u; ef[e[i].to]=e[i].w; dep[e[i].to]=dep[u]+1; t[e[i].to]=t[u]+e[i].w; } } } inline int swim(int x,int h){ for(int i=0;h;++i,h>>=1) if(h&1) x=f[x][i]; return x; } inline int lca(int x,int y){ int i,t; if(dep[x]<dep[y]){ t=x;x=y;y=t; } x=swim(x,dep[x]-dep[y]); if(x==y) return x; while(true){ for(i=0;f[x][i]!=f[y][i];++i); if(!i) return f[x][0]; x=f[x][i-1];y=f[y][i-1]; } } inline void total(int u){ s.push(u); memset(v,0,sizeof(v)); while(!s.empty()){ u=s.top(); if(!v[u]){ v[u]=true; for(int i=g[u];i;i=e[i].nxt) if(dep[e[i].to]>dep[u]) s.push(e[i].to); } else{ s.pop(); for(int i=g[u];i;i=e[i].nxt) if(dep[e[i].to]>dep[u]) w[u]+=w[e[i].to]; if(w[u]==sum){ flag=true; mk=max(mk,ef[u]); } } } } inline bool chk(int k){ int ma=0;mk=sum=0; memset(w,0,sizeof(w)); for(int i=1;i<=m;++i){ if(a[i].w>k){ ++sum;ma=max(ma,a[i].w); ++w[a[i].l];++w[a[i].r];w[a[i].f]-=2; } } flag=false;total(1); return flag&&ma-mk<=k; } inline void init(){ n=read();m=read(); for(int i=1,j,k,l;i<n;++i){ j=read();k=read();l=read(); addedge(j,k,l);addedge(k,j,l); } dfs(1); for(int i=1,j,k,l;i<=m;++i){ a[i].l=read();a[i].r=read(); a[i].f=lca(a[i].l,a[i].r); a[i].w=t[a[i].l]+t[a[i].r]-(t[a[i].f]<<1); } int l=0,r=INF,mid; while(l<r){ mid=(l+r)>>1; if(chk(mid)) r=mid; else l=mid+1; } printf("%d ",l); } int main(){ freopen("transport.in","r",stdin); freopen("transport.out","w",stdout); init(); fclose(stdin); fclose(stdout); return 0; }