運輸計劃sol
阿新 • • 發佈:2020-07-27
運輸計劃
最小化最大值問題,考慮用二分答案
check中一般用貪心策略
將每條路徑的長度預處理,對二分的ans,將長度比ans大的取出來
並找出這些路徑是否有一條重邊使得最長的路徑減了這條邊後小於ans
注意dfs中引數少一點會更快,將dfs中訪問順序存到陣列中,在每次check時不要再次dfs
陣列要開大一點。。
#include<bits/stdc++.h> #define fi first #define se second #define pb push_back #define mp make_pair #define SZ(x) ((int)x.size()) #define ALL(x) x.begin(),x.end() #define U(i,u) for(register ll i=head[u];i;i=nxt[i]) #define rep(i,a,b) for(register ll i=(a);i<=(b);++i) #define per(i,a,b) for(register ll i=(a);i>=(b);--i) using namespace std; typedef long double ld; typedef long long ll; typedef unsigned int ui; typedef pair<int,int> PII; typedef vector<int> VI; template<class T> inline void read(T &x){ x=0;char c=getchar();ll f=1; while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f; } template<class T> inline void cmin(T &x, T y){x=x<y?x:y;} template<class T> inline void cmax(T &x, T y){x=x>y?x:y;} const int N=1000100; ll n,m,head[N],nxt[N],v[N],cnt,uu[N],vi[N],li[N],anc[N][24]; ll w[N],su,mx,mxx,mi=9999999999,s[N],dep[N]; ll num[N],ct; ll vis[N],tmp; inline void add(ll x,ll y,ll z){nxt[++cnt]=head[x];head[x]=cnt;v[cnt]=y;w[cnt]=z;} inline void dfs(ll now,ll d){ vis[now]=1;num[++ct]=now;dep[now]=d;U(i,now){ if(vis[v[i]])continue;s[v[i]]=s[now]+w[i];anc[v[i]][0]=now;dfs(v[i],d+1); } } inline void init(){ memset(vis,0,sizeof(vis));dfs(1,0); rep(j,1,23)rep(i,2,n){anc[i][j]=anc[anc[i][j-1]][j-1];} } inline void swim(ll &x,ll h){ for(ll i=0;h;i++){ if(h&1)x=anc[x][i]; h>>=1; } } inline ll lca(ll x,ll y){ if(dep[x]<dep[y])swap(x,y); if(y==1)return 1; swim(x,dep[x]-dep[y]); if(x==y)return x; for(ll i=23;i>=0;i--){ if(anc[x][i]^anc[y][i]){ x=anc[x][i];y=anc[y][i]; } } return anc[x][0]; } inline bool check(ll an){ memset(vis,0,sizeof(vis)); tmp=0;rep(i,1,m){ if(dep[i]>an){ ++vis[uu[i]],++vis[vi[i]],vis[li[i]]-=2; ++tmp; } } if(!tmp)return 1; per(i,n,2)vis[anc[num[i]][0]]+=vis[num[i]]; rep(i,1,n)if(vis[i]>=tmp&&mx-(s[i]-s[anc[i][0]])<=an)return 1; return 0; } int main(){ read(n);read(m);ll a,b;ll c;rep(i,1,n-1){read(a);read(b);read(c);add(a,b,c);add(b,a,c);su+=c;cmax(mxx,c);} init();rep(i,1,m){read(uu[i]);read(vi[i]);li[i]=lca(uu[i],vi[i]);} rep(i,1,m){dep[i]=s[vi[i]]+s[uu[i]]-2*s[li[i]];cmax(mx,dep[i]);cmin(mi,dep[i]);} ll l=0,r=su,mid; while(r-l>=3){ mid=(r+l)>>1;if(check(mid))r=mid;else l=mid+1; } for(ll i=l;i<=r;i++){ if(check(i)){ printf("%lld\n",i); return 0; } } return 0; } /* 6 3 1 2 3 1 6 4 3 1 7 4 3 12 3 5 5 3 6 2 5 4 5 */