P2680_运输计划

#include<bits/stdc++.h>
#define o(x,y) make_pair(x,y)
using namespace std;
const int mn=3e5+7;
int fr[mn],nx[2*mn],to[2*mn],c[2*mn],tt,fr2[mn],nx2[2*mn],to2[2*mn],tt2=0;
int w[mn],f[mn],num[mn],v[mn];
bool p[mn],flag=0;
int mi=0x3f3f3f3f,mx=-1,n,m,mid,cnt=0;
struct ccf{
	int x,y,lca,sum;
}s[mn];
int ffind(int x)
{
	return f[x]==-1?x:f[x]=ffind(f[x]);
}
void add(int x,int y,int k)
{
	++tt;
	nx[tt]=fr[x];
	fr[x]=tt;
	to[tt]=y;
	c[tt]=k;
}
void add2(int x,int y)
{
	++tt2;
	nx2[tt2]=fr2[x];
	fr2[x]=tt2;
	to2[tt2]=y;
}
void dfs(int x,int fa)
{
	for(int i=fr[x];i;i=nx[i])
	{
		int y=to[i];
		if(y==fa)  continue;
		v[y]=c[i];
		w[y]=w[x]+c[i];
		dfs(y,x);
	}
	p[x]=1;
	for(int i=fr2[x];i;i=nx2[i])
	{
		int y=to2[i];
		if(p[y])
		{
			int k=(i+1)>>1,lca=ffind(y);
			s[k].lca=lca;
			s[k].sum=w[x]+w[y]-2*w[lca];
			mi=mi>s[k].sum?s[k].sum:mi;
			mx=mx<s[k].sum?s[k].sum:mx;
		}
	}
	f[ffind(x)]=ffind(fa);
	return ;
}
int dfs2(int x,int fa)
{
	int sum=num[x];
	for(int i=fr[x];i;i=nx[i])
	{
		int y=to[i];
		if(y==fa)  continue;
		sum+=dfs2(y,x);
		if(flag)  return 0;
	}
	if(sum==cnt&&mx-v[x]<=mid)  flag=1;
	return sum;
}
bool check(int k)
{
	flag=0;cnt=0;
	memset(num,0,sizeof(num));
	for(int i=1;i<=m;++i)
	  if(s[i].sum>k)
	  {
	  	++num[s[i].x];
	  	++num[s[i].y];
	  	num[s[i].lca]-=2;
	  	++cnt;
	  }
	if(cnt==0)  return true;
	dfs2(1,0);
	return flag;
}
int main()
{
	memset(f,-1,sizeof(f));
	cin>>n>>m;
	for(int i=1;i<n;++i)
	{
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		add(x,y,k);
		add(y,x,k);
	}
	for(int i=1;i<=m;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		s[i].x=x;s[i].y=y;
		add2(x,y);
		add2(y,x);
	}
	dfs(1,0);
	int l=0,r=mx,ans=0x3f3f3f3f;
	//cout<<s[1].sum;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid))
		{
			ans=ans>mid?mid:ans;
			r=mid-1;
		}
		else
		  l=mid+1;
	}
	printf("%d",ans);
	return 0;
} 
上一篇:Mininet源代码的目录结构


下一篇:初一数学月考答题分析案例