比赛 |
近期练习题回顾 |
评测结果 |
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;
}