比赛 近期练习题回顾 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 运输计划 最终得分 100
用户昵称 @@@ 运行时间 4.510 s
代码语言 C++ 内存使用 149.84 MiB
提交时间 2018-10-25 10:04:04
显示代码纯文本
#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int n,m,N,maxans;
int t[3000003][2],before[3000003];
int LCA,lcc[3000003];
int grand[300005][60],dis[300003],deep[300003];
int W[300003];
int cha[3000003];
struct  P{int v,w;};
vector<P> e[300005];
void dfs(int x)
{
	for (int i = 0; i < e[x].size(); ++i)
		if (grand[x][0] != e[x][i].v)
		{
			dfs(e[x][i].v);
			cha[x]+=cha[e[x][i].v];
		}
}
bool check(int x)
{
	int maxT = 0,cnt = 0;
	for(int i = 1;i <= n;i++)cha[i] = 0;
	for (int i = 1; i <= m; ++i)
	{
		if (before[i] > x)
		{
			cnt++;
			cha[lcc[i]]-=2;
			cha[t[i][0]]++;
			cha[t[i][1]]++;
			maxT = max(maxT,before[i]-x);
		}
	}
	dfs(1);
	int maax = 0;
	for(int i = 1;i <= n;i++)
		if(cnt == cha[i])
			maax = max(maax,W[i]);
	return maxT <= maax;
}
void build(int x)
{
	for (int i = 1; i <= N; ++i)
	{
		grand[x][i] = grand[grand[x][i-1]][i-1];
		if(grand[x][i] == 0)
			break;
	//	dis[x][i] = dis[x][i-1]+dis[grand[x][i-1]][i-1];
	}
	for (int i = 0; i < e[x].size(); ++i)
	{
		int t = e[x][i].v,ww = e[x][i].w;
		if (grand[x][0] != t)
		{
			grand[t][0] = x;
	//		dis[t][0] = ww;
			W[t] = ww;
			dis[t] = dis[x]+ww;
			deep[t] = deep[x]+1;
			build(t);
		}
	}
}
int lca(int x,int y)
{
	//int ass = 0;
	if (deep[x] > deep[y])swap(x,y);
	for (int i = N; i >= 0; --i)
	{
		//if (deep[x] < deep[y]&&grand[y][i]&&deep[grand[y][i]])
		if (deep[x] <= deep[grand[y][i]])
		{
		//	ass+=dis[y][i];
			y = grand[y][i];
		}
	}
	if (x == y)
	{
		//LCA = x;
		return x;
	}
	for (int i = N;i >= 0; --i)
	{
		if (grand[x][i] != grand[y][i])
		{
		//	ass += dis[x][i]+dis[y][i];
			x = grand[x][i];
			y = grand[y][i];
		}
	}
	if (x != y)
	{
		//LCA = grand[x][0];
		//ass += dis[x][0]+dis[y][0];
		return grand[x][0];
	}
	//LCA = x;
	return x;
}
int get_dis(int a,int b,int lll)
{
	return dis[a]+dis[b]-dis[lll]*2;
}
int main()
{
	freopen("transport.in","r",stdin);
	freopen("transport.out","w",stdout);
	scanf("%d%d",&n,&m);
	N = log2(n);
	//deep[1] = 1;
	int u,v,w;
	//grand[1][0] = 1;
	for (int i = 1; i < n; ++i)
	{
		scanf("%d%d%d",&u,&v,&w);
		e[u].push_back((P){v,w});
		e[v].push_back((P){u,w});
	}
	build(1);
	for (int i = 1; i <= m; ++i)
	{
		scanf("%d%d",&t[i][0],&t[i][1]);
		lcc[i] = lca(t[i][0],t[i][1]);
		maxans = max(maxans,before[i] = get_dis(t[i][0],t[i][1],lcc[i]));
		
	}
	int l = -1,r = maxans;
	while(r-l > 1)
	{
		int mid = (l + r) >> 1;
		if (check(mid))	r = mid;
		else l = mid;
	}
	printf("%d\n",r);
	//cout << r;
	return 0;
}