In other root dp

Such problems are seldom feel? Forget it, or come up with runoff about it qwq ...


First look at an example: POJ3585

A topic meaning: source tree any more than the maximum flow Meeting Point

You see this is not a problem of maximum flow board do? I would like to build a map, and then run the maximum flow, then ,,, then?

then

All the elements are nonnegative integers no more than 200000.

Measuring more than ... mdzz

Well, in terms of changing the root of it.

First, there is a violent \ (dp \) , we first consider \ (rt = 1 \) case ( \ (1 \) for the root), so \ (dp [x] \) represents \ (rt \) for the root when, directly to nodes \ (X \) irrigation, and the \ (X \) flow within the maximum flow subtree

It has the following transfer

\[ dp[x] = \sum\limits_{v \in son_x} \min\{dp[v], w(x,v)\} \]

In particular, if \ (V \) in \ (1 \) at the root of the case is a leaf node, then, \ (DP [X] + = W (X, V) \) ( \ (W (X, Y) \) represents the edge \ ((x, y) \ ) capacity)

Then \ (O (n) \) enumeration \ (RT \) , then \ (O (n) \) dp, can reap a \ (n ^ 2 \) of good practices.

Found that after changing the root of the tree is actually not so big, so we \ (f [x] \) represents \ (rt = x \) when \ (dp [the X-] \) .

Consider \ (rt \) change to the \ (x \) is a son \ (v \) , the due \ (x \) for the root when \ (v \) is (x \) \ a son, so \ (V \) be \ (f [x] \) generates \ (min (dp [v] , w (x, v)) \) contributed

Then \ (f [x] -min ( dp [v], w (x, v)) \) is obtained in addition to the sub-tree \ (V \) portion other than the root after changing it becomes \ (V \ ) subtree

So \ (F [V] DP = [V] + min \ left (W_ {X, V}, F [X] -min (DP [V], {X W_, V}) \ right) \) (Well ... too many brackets can not see ... so here it is directly \ (w_ {x, v} \) the qwq)

Need Laid sentence \ (X \) only \ (V \) a son when \ (F [V] = DP [V] + W_ {X, V} \) (directly from \ (V \) flow \ ( x \) a)

Therefore Code

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define fore(i,x) for(int i=head[x],v=e[i].to,w=e[i].w;i;i=e[i].nxt,v=e[i].to,w=e[i].w)
const int N=3e5+10;
struct edge
{
    int to,nxt,w;
}e[N<<1];
int head[N],cnt;
inline void ade(int x,int y,int w)
{e[++cnt]=(edge){y,head[x],w},head[x]=cnt;}
inline void addedge(int x,int y,int w)
{ade(x,y,w),ade(y,x,w);}
int n,sum[N],f[N],deg[N]; // 这里的sum就是上面的dp辣
void dfs(int x,int prev)
{
    fore(i,x) if(v!=prev)
    {
        dfs(v,x);
        if(deg[v]==1) sum[x]+=w;
        else sum[x]+=min(sum[v],w);
    }
}
void getans(int x,int prev)
{
    fore(i,x) if(v!=prev)
    {
        if(deg[x]==1) f[v]=sum[v]+w;
        else f[v]=sum[v]+min(f[x]-min(sum[v],w),w);
        getans(v,x);
    }
}
void sol()
{
    memset(deg,0,sizeof(deg));
    memset(sum,0,sizeof(sum));
    memset(f,0,sizeof(f));
    memset(head,0,sizeof(head));
    memset(e,0,sizeof(e));
    cnt=0;
    scanf("%d",&n);
    for(int x,y,w,i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&w);
        addedge(x,y,w);
        ++deg[x],++deg[y];
    }
    dfs(1,0);
    f[1]=sum[1],getans(1,0);
    int ans=0;
    for(int i=1;i<=n;i++)ans=max(ans,f[i]);
    printf("%d\n",ans);
}
int main()
{
    int T; scanf("%d",&T); while(T--)sol();
    return 0;
}

So look at a question: LuoguP3478

Similarly root change, so that \ (f [x] \) represents \ (X \) for all the nodes and the root depth.

Consider changing to root \ (x \) is a son \ (v \) on, then for the sub-tree \ (v \) inside the node, and their depth will reduce \ (1 \) , the other nodes will add depth \ (1 \) , i.e. ( \ (size_v \) represents \ (V \) to \ (1 \) subtree size when root)

\[f[v]=f[x]+n-size_v-size_v=f[x]+n-2\times size_v\]

First to \ (1 \) is calculated root \ (size \) , then change like a root

OI futile decade, not open long long to see fathers

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fore(i,x) for(int i=head[x],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
const int N=1e6+10;
int n;
struct edge
{
    int to,nxt;
}e[N<<1];
int head[N],cnt=0;
inline void ade(int x,int y)
{e[++cnt]=(edge){y,head[x]},head[x]=cnt;}
inline void addedge(int x,int y)
{ade(x,y),ade(y,x);}
ll f[N],dep[N];
int siz[N];
void dfs(int x,int prev,int deep)
{
    dep[x]=deep,siz[x]=1;
    fore(i,x) if(v!=prev)
        dfs(v,x,deep+1),siz[x]+=siz[v];
}
void getans(int x,int prev)
{
    fore(i,x) if(v!=prev)
    {
        f[v]=f[x]+n-2ll*siz[v];
        getans(v,x);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1,x,y;i<n;i++)
        scanf("%d%d",&x,&y),addedge(x,y);
    dfs(1,0,0); 
    for(int i=1;i<=n;i++) f[1]+=dep[i];
    getans(1,0);
    ll mx=0; int ans=0;
    for(int i=1;i<=n;i++)
        if(f[i]>mx) mx=f[i],ans=i;
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/wxq1229/p/12317448.html