比赛 近期练习题回顾 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 运输计划 最终得分 100
用户昵称 liuyu 运行时间 3.499 s
代码语言 C++ 内存使用 42.27 MiB
提交时间 2018-10-29 16:44:31
显示代码纯文本
#include<bits/stdc++.h>
#define ll long long
#define lc o<<1,l,mid
#define rc o<<1|1,mid+1,r
using namespace std;

inline void in(int &x){
	x=0;char c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
}
const int N=300000+10;
const int INF=(1<<30)-1+(1<<30);
int n,m,a,b,w;
struct edg{int to,w;};
vector<edg>v[N];//存图 
int dist[N];//放点上的边权
int cud[N<<2];//不经过次边的最长链的长度
int sum[N<<2];//链长和 
edg lr[N];//链对应的在dfs序中的区间
int llr;//区间个数 
int ans=2e9;//最终结果(最大值最小) 
int mx,my,maxl=0,lca;//最长链的x,y,长度l 
int s,t,x,y,su=0,nowl,bui=0;
int dfn[N],size[N],pos[N],top[N],son[N],eend[N],fa[N],deep[N];

void dfs1(int x);
void dfs2(int x,int root);
void init();

void build(int o,int l,int r);
void que(int o,int l,int r);
void que1(int o,int l,int r,int MAX);
void update(int o,int l,int r);

bool cmp(edg a,edg b){return a.to <b.to ;}

int main(){
	freopen("transport.in","r",stdin);
	freopen("transport.out","w",stdout);
	init();
	for(int i=1;i<=m;i++){
		in(x),in(y);//先求出链的长度、所有区间,再更新区间补集 
		nowl=0;llr=0; 
		int fx=top[x],fy=top[y],a=x,b=y,llc;
		while(fx!=fy){
			if(deep[fx]>=deep[fy])
				 s=pos[fx],t=pos[x],que(1,1,n),x=fa[fx],lr[++llr].to=s,lr[llr].w=t;
			else s=pos[fy],t=pos[y],que(1,1,n),y=fa[fy],lr[++llr].to=s,lr[llr].w=t;
			fx=top[x],fy=top[y];//cout<<"====="<<nowl<<" "<<x<<" "<<y<<endl;
		}
		if(x!=y){
			if(pos[x]>pos[y])swap(x,y);
			s=pos[x]+1,t=pos[y];que(1,1,n);//cout<<x<<" "<<y<<" "<<s<<" "<<t<<" "<<i<<" "<<nowl<<endl;
			lr[++llr].to=s,lr[llr].w=t;
		}llc=x;
		if(nowl>maxl)maxl=nowl,mx=a,my=b,lca=llc;
		s=1;
	//cout<<a<<" "<<b<<" "<<nowl<<" "<<lca<<endl;
		sort(lr+1,lr+llr+1,cmp);
		for(int j=1;j<=llr;j++){
			if(j==1){
				if(lr[j].to==1)continue;
				else t=lr[j].to-1;
			}else s=lr[j-1].w+1,t=lr[j].to-1;
			if(s>t)continue;
			else update(1,1,n);
		}
		if(lr[llr].w<n)s=lr[llr].w+1,t=n,update(1,1,n);
	}
	while(mx!=lca){
		nowl=0;s=pos[mx];que1(1,1,n,0);//cout<<mx<<"---mXXXX: "<<nowl<<" "<<maxl-dist[my]<<endl;
		ans=min(ans,max(maxl-dist[mx],nowl));
		mx=fa[mx];
	}while(my!=lca){
		nowl=0;s=pos[my];que1(1,1,n,0);//cout<<my<<"---mYYYY: "<<nowl<<" "<<maxl-dist[my]<<endl;
		ans=min(ans,max(maxl-dist[my],nowl));
		my=fa[my];
	}
	cout<<ans<<endl;
	//for(int i=1;i<=n;i++)cout<<i<<" "<<pos[i]<<endl;
	return 0;
}

void build(int o,int l,int r){
	if(l==r)sum[o]=dist[dfn[++bui]];
	else{
		int mid=(l+r)>>1;
		build(lc),build(rc);
		sum[o]=sum[o<<1]+sum[o<<1|1];
	}
}

void que(int o,int l,int r){//nowl
	if(s<=l&&r<=t)nowl+=sum[o];
	else{
		int mid=(l+r)>>1;
		if(s<=mid)que(lc);
		if(t>mid)que(rc);
	}
}

void update(int o,int l,int r){
	if(s<=l&&r<=t)cud[o]=max(cud[o],nowl);
	else{
		int mid=(l+r)>>1;
		if(s<=mid)update(lc);
		if(t>mid)update(rc);
		//cud[o]=max(cud[o],max(cud[o<<1],cud[o<<1|1]));
	}
}

void que1(int o,int l,int r,int MAX){
	if(l==r)nowl=max(cud[o],MAX);
	else{
		int mid=(l+r)>>1;
		if(s<=mid)que1(lc,max(MAX,cud[o]));
		else que1(rc,max(MAX,cud[o]));
	}
}

void init(){
	in(n),in(m);
	for(int i=1;i<n;i++){
		in(a),in(b),in(w);
		v[a].push_back((edg){b,w});
		v[b].push_back((edg){a,w});
	}
	//size[]son[]deep[]fa[]
	deep[1]=1;fa[1]=1;
	dfs1(1);
	//dfn[]top[]eend[]
	dfn[++su]=1;
	top[1]=1;
	dfs2(1,1);
	for(int i=1;i<=su;i++)pos[dfn[i]]=i;
	build(1,1,n);
}

void dfs1(int x){//size[]son[]deep[]fa[]
	int maxsize=0;
	if(v[x].size()==1&&x!=1){size[x]=1;return;}
	size[x]=1;
	for(int i=0;i<v[x].size();i++){
		edg e=v[x][i];
		if(fa[x]!=e.to){
			deep[e.to]=deep[x]+1;
			fa[e.to]=x;
			dist[e.to]=e.w;
			dfs1(e.to);
			size[x]+=size[e.to];
			if(size[e.to]>maxsize)
				maxsize=size[e.to],
				son[x]=e.to;
		}
	}
}

void dfs2(int x,int root){//dfn[]top[]eend[]
	int f=1;
	if(son[x]){
		f=0;
		dfn[++su]=son[x];
		top[son[x]]=root;
		dfs2(son[x],root);
	}
	for(int i=0;i<v[x].size();i++){
		edg e=v[x][i];
		if(fa[x]!=e.to&&e.to!=son[x]){
			if(f)top[e.to]=root,f=0;
			else top[e.to]=e.to;
			dfn[++su]=e.to;
			dfs2(e.to,e.to);
		}
	}
	eend[x]=su;
}

/*
6 3 
1 2 3 
1 6 4 
3 1 7 
4 3 6 
3 5 5 
3 6 
2 5 
4 5
*/