POJ 3585 Accumulation Degree(换根dp)

Topic portal

Question: There is a tree, and each edge of the tree has a traffic limit. The traffic value of a node is the sum of the traffic that can reach the leaf node from it. What is your maximum flow value?

Idea: First traverse the tree with 1 as the root, use sum[i] to represent the maximum flow of subtree i, and f[i] to represent the maximum flow of the entire tree when i is the root node. When we move from node x to its child node y, we can derive the state transition equation:

  • s u m [ x ] + = ( d u [ y ] = = 1 ) ? d i s ( x , y ) : m i n ( s u m [ y ] , d i s ( x , y ) ) sum[x]+=(du[y]==1)?dis(x,y):min(sum[y],dis(x,y)) sum[x]+=( d u [ y ]==1)?dis(x,and ):min(sum[y],dis(x,and ) )
  • f [ y ] = m i n ( f [ x ] − m i n ( d i s ( x , y ) , s u m [ y ] ) , d i s ( x , y ) ) + s u m [ y ] f[y]=min(f[x]-min(dis(x,y),sum[y]),dis(x,y))+sum[y] f[y]=m and n ( f [ x ]m i n ( d i s ( x ,and ) ,s u m [ y ] ) ,dis(x,and ) )+s u m [ y ]

However, a special case needs to be considered, that is, if x is a leaf node, then the state transition equation is:

  • f [ y ] = s u m [ y ] + d i s ( x , y ) f[y]=sum[y]+dis(x,y) f[y]=s u m [ y ]+dis(x,and )

Code:

//#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<ctype.h>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<vector>
#define endl '\n'
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
//char *fs,*ft,buf[1<<20];
//#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
//inline int read()
//{
    
    
//    int x=0,f=1;
//    char ch=gc();
//    while(ch<'0'||ch>'9')
//    {
    
    
//        if(ch=='-')
//            f=-1;
//        ch=gc();
//    }
//    while(ch>='0'&&ch<='9')
//    {
    
    
//        x=x*10+ch-'0';
//        ch=gc();
//    }
//    return x*f;
//}
using namespace std;
const int N=201000;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-7;

vector< pair<int,int> >e[N];
int f[N],sum[N];

void dfs(int fa,int x)
{
    
    
    for(int j=0; j<e[x].size(); j++)
    {
    
    
        pair<int,int> i = e[x][j];
        if(i.first==fa)
            continue;
        dfs(x,i.first);
        if(e[i.first].size()==1)
            sum[x] += i.second;
        else
            sum[x] += min(i.second,sum[i.first]);
    }
}
void ddfs(int fa,int x)
{
    
    
    for(int j=0; j<e[x].size(); j++)
    {
    
    
        pair<int,int> i = e[x][j];
        if(i.first==fa)
            continue;
        if(e[x].size()!=1)
            f[i.first] = sum[i.first] + min(i.second,f[x]-min(i.second,sum[i.first]));
        else
            f[i.first] = sum[i.first] + i.second;
        ddfs(x,i.first);
    }
}

void solve()
{
    
    
    int n;
    cin>>n;
    for(int i=1; i<=n-1; i++)
    {
    
    
        int u,v,w;
        cin>>u>>v>>w;
        e[u].pb(mp(v,w));
        e[v].pb(mp(u,w));
    }
    dfs(1,1);
    f[1] = sum[1];
    ddfs(1,1);
    cout<<*max_element(f+1,f+n+1)<<endl;
    for(int i=1; i<=n; i++)
    {
    
    
        e[i].clear();
        f[i] = 0;
        sum[i] = 0;
    }
}

signed main()
{
    
    
    int _;
    cin>>_;
    while(_--)
        solve();

    return 0;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/113014494