LGOJ P5021 track construction

LGOJ P5021 track construction

Half the answer, greedy

(LCA finished the board only to find that he will not do it)

Shaped like:

Minimization of the maximum
minimization of the maximum value

Such a thing, in all likelihood is half the answer.

In this scenario we have half of the current track allows the shortest length \ (L \) . We will check, in the shortest length \ (L \) under the limit, can not less than m track structure. If you can let \ (L \) bigger, if not it a little.

So now consider, in the current track has allowed the shortest length \ (L \) able to open up to several restrictions under the track.

Is defined: \ (F [U] \) is \ (U \) the maximum length of the track to contribute to the parent node of node direction. \ (CNT \) is the number of the current track have been constructed, the initial value \ (0 \) . With (\ w (u, v) ) \ represents \ (U \) to \ (V \) path length.

We get a map, a partial view of the shape: "broom" broom handle is \ (U \) to the parent node \ (FA \) path, each of the broom to be expressed \ (U \) to child nodes \ (V_I \) a path, each of the broom to be adhered to the top of a small garbage \ (V_I \) . We assume that in the current circumstances, all of \ (f [v_i] \) have been calculated.

We shall first broom in accordance with (f [v_i] + w ( u, v_i) \) \ ascending order, shall consider these broom \ (^ * \) ;

  1. If a required length of the root broom \ (w (u, v_i) \) the greatest contribution plus child nodes \ (f [v_i] \) has greater than or equal \ (L \) , and it shows that we get a legitimate It tracks, cnt++and this must be unplugged from the broom broom.
  2. If the current shortest Flanagan broom broom must be able to find another subject, making it a two brooms to be just like \ (L \) big or just right equal to \ (L \) , then these two must have pulled the broom so we get a legitimate track cnt++. Note that, here just right, is strictly just right, i.e., the combination of the current state, so that the latter can not exist in other combinations than or equal to the length of both \ (L \) surpasses the combined length of the current small.
  3. If the current broom to be too short, so that the above two conditions are not met, then consider this to be the root of the broom may keep more parent paths are combined to get a new track, and can award broom be unique, because all paths can only be used once. Then, the state transition equation can be listed:
    \ [F [U] = max (F [V_I] + W (U, V_I)), \ Quad V_I \ in Son (U) \]

Such a broom to consider the full.

Now consider the full picture, then we \ (dfs \) to consider their broom, where the boundary conditions: the initial value of the leaf node is clear: \ (f [Leaf] = 0 \) .

Then compare the size of cnt and m relationship, we can know \ (L \) of how the values should be adjusted.

It is not over yet. Consider these brooms to be \ (^ * \) That step involves a question of order, we use multisetoptimization, so we got some lovely \ (log \) .

The complexity of breaking a breaking fingers found not count ...... estimated to be \ (O (n \ log ^ 2 n) \) about?

code:

#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    char c=getchar();int x=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x;
}
const int N=50005,INF=0x3f3f3f3f;
int n,m,cnt,curl;
int f[N];

struct node
{
    int v,w;
    node(){}
    node(int to,int weight)
    {
        v=to;
        w=weight;
    }
};
vector<node> G[N];

void dfs(int u,int fa)
{
    multiset<int> S;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i].v,w=G[u][i].w;
        if(v!=fa)
        {
            dfs(v,u);
            if(f[v]+w>=curl)cnt++;
            else S.insert(f[v]+w);
        }
    }
    while(!S.empty())
    {
        multiset<int>::iterator it_cur=S.begin();
        S.erase(it_cur);
        multiset<int>::iterator it=S.lower_bound(curl-*it_cur);
        if(it!=S.end())cnt++,S.erase(it);
        else f[u]=max(f[u],*it_cur);
    }
}

inline bool chk(int x)
{
    memset(f,0,sizeof(f));
    cnt=0;
    curl=x;
    dfs(1,0);
    if(cnt>=m)return 1;
    else return 0;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<n;i++)
    {
        int u=read();
        int v=read();
        int w=read();
        G[u].push_back(node(v,w));
        G[v].push_back(node(u,w));
    }
    int l=0,r=INF,mid,ans=0;
    while(l<=r)
    {
        mid=((l+r)>>1);
        if(chk(mid))
        {
            ans=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    cout<<ans;
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    char c=getchar();int x=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x;
}
const int N=50005,INF=0x3f3f3f3f;
int n,m,cnt,curl;
int f[N];

struct node
{
    int v,w;
    node(){}
    node(int to,int weight)
    {
        v=to;
        w=weight;
    }
};
vector<node> G[N];

void dfs(int u,int fa)
{
    multiset<int> S;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i].v,w=G[u][i].w;
        if(v!=fa)
        {
            dfs(v,u);
            if(f[v]+w>=curl)cnt++;
            else S.insert(f[v]+w);
        }
    }
    while(!S.empty())
    {
        multiset<int>::iterator it_cur=S.begin();
        S.erase(it_cur);
        multiset<int>::iterator it=S.lower_bound(curl-*it_cur);
        if(it!=S.end())cnt++,S.erase(it);
        else f[u]=max(f[u],*it_cur);
    }
}

inline bool chk(int x)
{
    memset(f,0,sizeof(f));
    cnt=0;
    curl=x;
    dfs(1,0);
    if(cnt>=m)return 1;
    else return 0;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<n;i++)
    {
        int u=read();
        int v=read();
        int w=read();
        G[u].push_back(node(v,w));
        G[v].push_back(node(u,w));
    }
    int l=0,r=INF,mid,ans=0;
    while(l<=r)
    {
        mid=((l+r)>>1);
        if(chk(mid))
        {
            ans=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    cout<<ans;
    return 0;
}

------------ restore the contents of the end ------------
LGOJ track built P5021

#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    char c=getchar();int x=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x;
}
const int N=50005,INF=0x3f3f3f3f;
int n,m,cnt,curl;
int f[N];

struct node
{
    int v,w;
    node(){}
    node(int to,int weight)
    {
        v=to;
        w=weight;
    }
};
vector<node> G[N];

void dfs(int u,int fa)
{
    multiset<int> S;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i].v,w=G[u][i].w;
        if(v!=fa)
        {
            dfs(v,u);
            if(f[v]+w>=curl)cnt++;
            else S.insert(f[v]+w);
        }
    }
    while(!S.empty())
    {
        multiset<int>::iterator it_cur=S.begin();
        S.erase(it_cur);
        multiset<int>::iterator it=S.lower_bound(curl-*it_cur);
        if(it!=S.end())cnt++,S.erase(it);
        else f[u]=max(f[u],*it_cur);
    }
}

inline bool chk(int x)
{
    memset(f,0,sizeof(f));
    cnt=0;
    curl=x;
    dfs(1,0);
    if(cnt>=m)return 1;
    else return 0;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<n;i++)
    {
        int u=read();
        int v=read();
        int w=read();
        G[u].push_back(node(v,w));
        G[v].push_back(node(u,w));
    }
    int l=0,r=INF,mid,ans=0;
    while(l<=r)
    {
        mid=((l+r)>>1);
        if(chk(mid))
        {
            ans=mid;
            l=mid+1;
        }
        else r=mid-1;
    }
    cout<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/kion/p/11835009.html