[Noip2015]運輸計劃
阿新 • • 發佈:2017-07-28
tin 描述 break scrip || pre ora turn names 開始,所有飛船一起出發。當這m個運輸計劃都完成時,小P的物流公司的階段性工作就完成了。
接下來n-1行描述航道的建設情況,其中第i行包含三個整數ai, bi和ti,表示第i條雙向航道修建在ai與bi兩個星球之間,任意飛船駛過它所花費的時間為ti。
接下來m行描述運輸計劃的情況,其中第j行包含兩個正整數uj和vj,表示第j個運輸計劃是從uj號星球飛往vj號星球。
Description
公元2044年,人類進入了宇宙紀元。
L國有n個星球,還有n-1條雙向航道,每條航道建立在兩個星球之間,這n-1條航道連通了L國的所有星球。
小P掌管一家物流公司,該公司有很多個運輸計劃,每個運輸計劃形如:有一艘物流飛船需要從ui號星球沿最快的宇航路徑飛行到vi號星球去。顯然,飛船駛過一條航道是需要時間的,對於航道j,任意飛船駛過它所花費的時間為tj,並且任意兩艘飛船之間不會產生任何幹擾。
為了鼓勵科技創新,L國國王同意小P的物流公司參與L國的航道建設,即允許小P把某一條航道改造成蟲洞,飛船駛過蟲洞不消耗時間。
在蟲洞的建設完成前小P的物流公司就預接了m個運輸計劃。在蟲洞建設完成後,這m個運輸計劃會同時
如果小P可以自由選擇將哪一條航道改造成蟲洞,試求出小P的物流公司完成階段性工作所需要的最短時間是多少?
Input
第一行包括兩個正整數n、m,表示L國中星球的數量及小P公司預接的運輸計劃的數量,星球從1到n編號。接下來n-1行描述航道的建設情況,其中第i行包含三個整數ai, bi和ti,表示第i條雙向航道修建在ai與bi兩個星球之間,任意飛船駛過它所花費的時間為ti。
接下來m行描述運輸計劃的情況,其中第j行包含兩個正整數uj和vj,表示第j個運輸計劃是從uj號星球飛往vj號星球。
Output
共1行,包含1個整數,表示小P的物流公司完成階段性工作所需要的最短時間。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
樣例說明】
將第1條航道改造成蟲洞:則三個計劃耗時分別為:11、12、11,故需要花費的時間為12。
將第2條航道改造成蟲洞:則三個計劃耗時分別為:7、15、11,故需要花費的時間為15。
將第3條航道改造成蟲洞:則三個計劃耗時分別為:4、8、11,故需要花費的時間為11。
將第4條航道改造成蟲洞:則三個計劃耗時分別為:11、15、5,故需要花費的時間為15。
將第5條航道改造成蟲洞:則三個計劃耗時分別為:11、10、6,故需要花費的時間為11。
故將第3條或第5條航道改造成蟲洞均可使得完成階段性工作的耗時最短,需要花費的時間為11。
【數據規模與約定】
所有測試數據的範圍和特點如下表所示
#include<bits/stdc++.h> #define MAXN 300005 using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } struct Node{int v,w;}; struct Edge { int u,v,lca,s; bool operator <(const Edge &a)const{return s>a.s;} }e[MAXN]; vector<Node>g[MAXN]; int deep[MAXN],p[MAXN][25],dis[MAXN],n,m,maxE,maxx,sum[MAXN]; inline void dfs(int u,int fa) { for(int i=0;i<g[u].size();i++) { int v=g[u][i].v; if(v==fa) continue; deep[v]=deep[u]+1; p[v][0]=u; dis[v]=dis[u]+g[u][i].w; dfs(v,u); } } void init() { dfs(1,0); for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) p[i][j]=p[p[i][j-1]][j-1]; } inline int lca(int u,int v) { if(deep[u]>deep[v]) swap(u,v); for(int i=20;i>=0;i--) if(deep[p[v][i]]>=deep[u]) v=p[v][i]; if(u==v) return u; for(int i=20;i>=0;i--) if(p[u][i]!=p[v][i]) { u=p[u][i]; v=p[v][i]; } return p[u][0]; } inline void getsum(int u,int fa,int tot) { for(int i=0;i<g[u].size();i++) { int v=g[u][i].v; if(v==fa) continue; getsum(v,u,tot); sum[u]+=sum[v]; if(sum[v]==tot) maxx=max(maxx,g[u][i].w); } } inline bool check(int mid) { if(e[1].s-mid>maxE) return 1; if(mid>=e[1].s) return 0; memset(sum,0,sizeof(sum)); int tot=0; for(int i=1;i<=m;i++) { if(e[i].s<=mid) break; sum[e[i].u]+=1; sum[e[i].v]+=1; sum[e[i].lca]-=2; tot++; } maxx=0; getsum(1,0,tot); if(maxx>=e[1].s-mid) return 0; return 1; } int main() { n=read(),m=read(); for(int i=1,u,v,w;i<=n-1;i++) { u=read(),v=read(),w=read(); g[u].push_back((Node){v,w}); g[v].push_back((Node){u,w}); maxE=max(maxE,w); } init(); for(int i=1,u,v;i<=m;i++) { u=read(),v=read(); int t=lca(u,v); e[i]=(Edge){u,v,t,dis[u]+dis[v]-2*dis[t]}; } sort(e+1,e+m+1); int l=0,r=e[1].s,ans; while(l<=r) { int mid=(l+r)>>1; if(check(mid))l=mid+1; else { ans=mid; r=mid-1; } } printf("%d",ans); }
[Noip2015]運輸計劃