洛谷2680 运输计划(树上差分)

传送门

【题目分析】

tnnd。。。。。竟然卡树剖?95pts在逗我?

试了各种卡常均gg。。。。。

所以我先贴95pts树剖,tarjan什么的等我心情好了再补。。。。mmp

【代码~(不要吐槽写得丑)】

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+10;
const int MAXM=6e5+10;

int n,m,cnt,pts;
int s[MAXN],t[MAXN],lc[MAXN],len[MAXN],deep[MAXN];

const int RLEN=1<<18|1;
char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
int Read() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-') f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

void swap(int &x,int &y){
	int t=x;
	x=y,y=t;
}

namespace SLPF{
	int head[MAXN],depth[MAXN],siz[MAXN],fa[MAXN],son[MAXN],top[MAXN];
	int nxt[MAXM],to[MAXM],w[MAXM];
	int dfn[MAXN],tot;
	int a[MAXN],delta[MAXN];
	
	void init(){
		memset(head,-1,sizeof(head[0])*(pts+5));
	}

	void add(int x,int y,int z){
		nxt[cnt]=head[x];
		head[x]=cnt;
		to[cnt]=y;
		w[cnt]=z;
		cnt++;
	}
	
	void dfs1(int u,int f){
		siz[u]=1;
		for(register int i=head[u];i!=-1;i=nxt[i]){
			int v=to[i];
			if(v==f)
			  continue;
			a[v]=w[i];
			depth[v]=depth[u]+1;
			deep[v]=deep[u]+w[i];
			fa[v]=u;
			dfs1(v,u);
			siz[v]+=siz[u];
			if(siz[v]>siz[son[u]])
			  son[u]=v;
		}
	}
	
	void dfs2(int u,int tp){
		top[u]=tp;
		dfn[u]=++tot;
		if(!son[u])
		  return ;
		dfs2(son[u],tp);
		for(register int i=head[u];i!=-1;i=nxt[i]){
			int v=to[i];
			if(v==fa[u]||v==son[u])
			  continue;
			dfs2(v,v);
		}
	}
	
	int lca(int x,int y){
		while(top[x]!=top[y]){
			if(depth[top[x]]<depth[top[y]])
			  swap(x,y);
			x=fa[top[x]];
		}
		return depth[x]<depth[y]?x:y;
	}
	
	void dfss(int u,int f){
		for(register int i=head[u];i!=-1;i=nxt[i]){
			int v=to[i];
			if(v==f)
			  continue;
			dfss(v,u);
			delta[u]+=delta[v];
		}
	}
	
	bool check(int x){
		int sum=0,ss=0;
		memset(delta,0,sizeof(delta[0])*(pts+5));
		for(register int i=1;i<=m;++i){
			if(len[i]>x){
				sum++;
				ss=max(ss,len[i]-x);
				delta[s[i]]++;
				delta[t[i]]++;
				delta[lc[i]]-=2;
			}
		}
		dfss(1,-1);
		for(register int i=1;i<=n;++i){
			if(delta[i]==sum&&a[i]>=ss)
			  return 1;
		}
		return 0;
	}
}

int main(){
	int l=0,r=5e7+7;
	n=Read(),m=Read();
	pts=n+2;
	SLPF::init();
	int x,y,z;
	for(int i=1;i<n;++i){
		x=Read(),y=Read(),z=Read();
		SLPF::add(x,y,z),SLPF::add(y,x,z);
	}
	SLPF::dfs1(1,-1);
	SLPF::dfs2(1,1);
	for(register int i=1;i<=m;++i)
	  s[i]=Read(),t[i]=Read(),lc[i]=SLPF::lca(s[i],t[i]),len[i]=deep[s[i]]+deep[t[i]]-deep[lc[i]]*2,r=max(r,len[i]);;
	int mid;
	while(l<=r){
		mid=l+r>>1;
		if(SLPF::check(mid))
		  r=mid-1;
		else
		  l=mid+1;
	}
	cout<<l;
	return 0;
}

 

posted @ 2018-11-05 22:07  Ishtar~  阅读(118)  评论(0编辑  收藏  举报