[AGC007E]Shik and Travel-动态规划-二分答案

Shik and Travel

Problem Statement

In the country there are N cities numbered 1 through N , which are connected by N1 bidirectional roads. In terms of graph theory, there is a unique simple path connecting every pair of cities. That is, the N cities form a tree. Besides, if we view city 1 as the root of this tree, the tree will be a full binary tree (a tree is a full binary tree if and only if every non-leaf vertex in the tree has exactly two children). Roads are numbered 1 through N1. The i -th road connects city i+1 and city ai . When you pass through road i , the toll you should pay is vi (if vi is 0 , it indicates the road does not require a toll).

A company in city 1 will give each employee a family travel and cover a large part of the tolls incurred. Each employee can design the travel by themselves. That is, which cities he/she wants to visit in each day and which city to stay at each night. However, there are some constraints. More details are as follows:

The travel must start and end at city 1 . If there are m leaves in the tree formed by the cities, then the number of days in the travel must be m+1 . At the end of each day, except for the last day, the employee must stay at some hotel in a leaf city. During the whole travel, the employee must stay at all leaf cities exactly once.

During the whole travel, all roads of the country must be passed through exactly twice.

The amount that the employee must pay for tolls by him/herself is the maximum total toll incurred in a single day during the travel, except the first day and the last day. The remaining tolls will be covered by the company.

Shik, as an employee of this company, has only one hope for his travel. He hopes that the amount he must pay for tolls by himself will be as small as possible. Please help Shik to design the travel which satisfies his hope.

Constraints

2<N<131,072
1aii for all i
0vi131,072
vi is an integer
The given tree is a full binary tree

Input

The input is given from Standard Input in the following format:

N
a1 v1
a2 v2
:
aN−1 vN−1

Output

Print an integer denoting the minimum amount Shik must pay by himself for tolls incurred during the travel.

Sample Input 1

7
1 1
1 1
2 1
2 1
3 1
3 1

Sample Output 1

4

There are 4 leaves in the tree formed by the cities (cities 4, 5, 6, and 7), so the travel must be 5 days long. There are 4!=24 possible arrangements of the leaf cities to stay during the travel, but some of them are invalid. For example, (4,5,6,7) and (6,7,5,4) are valid orders, but (5,6,7,4) is invalid because the route passes 4 times through the road connecting city 1 and city 2. The figure below shows the routes of the travel for these arrangements.

pic1
For all valid orders, day 3 is the day with the maximum total incurred toll of 4, passing through 4 roads.

Sample Input 2

9
1 2
1 2
3 2
3 2
5 2
5 2
7 2
7 2

Sample Output 2

6

The following figure shows the route of the travel for one possible arrangement of the stayed cities for the solution. Note that the tolls incurred in the first day and the last day are always covered by the company.

pic2

Sample Input 3

15
1 2
1 5
3 3
4 3
4 3
6 5
5 4
5 3
6 3
3 2
11 5
11 3
13 2
13 1

Sample Output 3

15

Sample Input 4

3
1 0
1 0

Sample Output 4

0

想到方法却不会证明复杂度系列……
神题一道.jpg


思路:
考虑先二分答案,那么现在问题变成了判定合法性。
只要咱们可以构建出一个合法的,且除了第一条和最后一条路径外,没有一条路径边权超过当前二分答案的方案,即可说明其合法性。

那么,考虑如何证明这样方案的存在性:
由于一条边经过次数不超过2,可以很容易发现这样的事实:一旦你进入了某棵子树,只有走完了里面的所有叶子结点,才可以出去。

那么考虑维护一种二元组,形如 (a,b)u ,代表以当前节点 u 为根节点的子树中,入边的长度为a,出边的长度为 b ,且这棵子树内部存在至少一条合法路径满足权值小于等于二分的答案,的一种方案。

于是每个节点均可以使用vector存储若干个方案,可以很轻松的转移:
(a,b)u=(a,i)ch[0]+(j,b)ch[1](i+j<=ans)
注意二元组的 a,b 可以互换。

然而可以发现根节点的方案数将会等于爆搜搜到的方案数。
考虑优化状态数,可以发现对于每个 a ,只会需求最小的一个合法的b配对,同理 b 也是这样。

那么,分割线下为本蒟蒻未想到的部分……


考虑启发式合并,可以发现statecount(u)<=2min(statecount(ch[0]),statecount(ch[1])),因为咱们总是可以选取较小的那一边,此时每个 a b最多只会贡献一种新方案。
于是状态数变成 O(nlogn) ,复杂度是十分正确的 O(nlognlogv)

于是做完了~

#include<bits/stdc++.h>

using namespace std;

inline int read()
{
    int x=0;char ch=getchar();
    while(ch<'0'|| ch>'9')ch=getchar();
    while('0'<=ch && ch<='9')x=x*10+(ch^48),ch=getchar();
    return x;
}

typedef long long ll;
typedef pair<ll,ll> pr;
typedef vector<pr> vec;
#define x first
#define y second
const int N=131100;

int n,fa[N];
vec g[N],f[N];
ll mid,mv[N];

inline bool cmpx(pr a,pr b){return a.x<b.x;}
inline bool cmpy(pr a,pr b){return a.y<b.y;}

inline void work(vec &ls,vec &rs,vec &f)
{
    if(ls.size()>rs.size())swap(ls,rs);
    int el=ls.size(),er=rs.size();

    sort(ls.begin(),ls.end(),cmpy);
    sort(rs.begin(),rs.end(),cmpx);

    mv[0]=rs[0].y;
    for(int i=1;i<er;i++)
        mv[i]=min(mv[i-1],rs[i].y);

    for(int i=0,j=er-1;i<el;i++)
    {
        while(j>=0 && ls[i].y+rs[j].x>mid)j--;
        if(j>=0)f.push_back(pr(ls[i].x,mv[j]));
    }

    sort(ls.begin(),ls.end(),cmpx);
    sort(rs.begin(),rs.end(),cmpy);
    mv[0]=rs[0].x;
    for(int i=1;i<er;i++)
        mv[i]=min(mv[i-1],rs[i].x);

    for(int i=0,j=er-1;i<el;i++)
    {
        while(j>=0 && ls[i].x+rs[j].y>mid)j--;
        if(j>=0)f.push_back(pr(mv[j],ls[i].y));
    }
}

inline void dfs(int u)
{
    if(!f[u].empty())f[u].clear();
    if(g[u].empty())
    {
        f[u].push_back(pr(0,0));
        return;
    }

    for(int i=0,e=g[u].size();i<e;i++)
        dfs(g[u][i].x);

    vec &ls=f[g[u][0].x];
    for(int i=0,e=ls.size(),c=g[u][0].y;i<e;i++)
        ls[i].x+=c,ls[i].y+=c;
    vec &rs=f[g[u][1].x];
    for(int i=0,e=rs.size(),c=g[u][1].y;i<e;i++)
        rs[i].x+=c,rs[i].y+=c;

    work(ls,rs,f[u]);
    ls.clear();
    rs.clear();
}

int main()
{
    n=read();
    for(int i=2,a;i<=n;i++)
    {
        fa[i]=read();
        g[fa[i]].push_back(pr(i,read()));
    }

    ll l=0,r=1e10,ans=1e10;
    while(l<=r)
    {
        mid=l+r>>1;
        dfs(1);
        if(f[1].empty())
            l=mid+1;
        else
            r=mid-1,ans=mid;
    }

    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值