zoukankan      html  css  js  c++  java
  • 【POJ3585】Accumulation Degree

    有关树形dp+二次扫描与换根法

    首先我们读入数据,用邻接表存储,并记录每一个点相连的边的数量。

    我们不妨先暂时假定节点1为树根,定义d[x]表示在以x为根的子树当中最大的流量,显然得出状态转移方程

    d[x]=∑min(d[y],c(x,y))  其中y∈son(x).

    求出了d数组,我们考虑“二次扫描与换根法”,定义f[x]表示以x为这棵树的根时的最大流量。那么f[x]包括两部分:

    1. 以x为根,流向x的儿子们的流量,这部分的答案即为d[x]
    2. 从x流向x的父亲,进而流向其他的节点,这一部分的答案我们可以这样考虑:把x作为根时流量为f[x],从x流向x的儿子y的流量为min(d[y],c(x,y)),所以x的流量减去这部分流量得到的差值就是剩余部分的流量。于是,把y作为原点,从y流向x的流量就是这个差值与c(x,y)取最小值的结果。因此不难得出状态转移方程f[y]=d[y]+min(f[x]-min(d[y],c(x,y)),c(x,y))
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <stack>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <cstring>
     7 #include <cmath>
     8 #define maxx 200005
     9 using namespace std;
    10 int head[maxx],to[maxx<<1],w[maxx<<1],_next[maxx<<1];
    11 int d[maxx];
    12 int cnt=0;
    13 int deg[maxx];
    14 void addEdge(int x,int y,int _w) {
    15     to[++cnt]=y,w[cnt]=_w,_next[cnt]=head[x],head[x]=cnt;
    16     to[++cnt]=x,w[cnt]=_w,_next[cnt]=head[y],head[y]=cnt;
    17 }
    18 int n;
    19 void dfs1(int root,int fa) {
    20     d[root]=0;
    21     for(int i=head[root]; i; i=_next[i]) {
    22         int v=to[i];
    23         if(v==fa)
    24             continue;
    25         dfs1(v,root);
    26         if(deg[v]==1)
    27             d[root]+=w[i];
    28         else
    29             d[root]+=min(w[i],d[v]);
    30     }
    31 }
    32 int f[maxx];
    33 void dfs2(int root,int fa) {
    34     for(int i=head[root]; i; i=_next[i]) {
    35         int v=to[i];
    36         if(v==fa)
    37             continue;
    38         if(deg[root]==1)
    39             f[v]=d[v]+w[i];
    40         else
    41             f[v]=d[v]+min(f[root]-min(w[i],d[v]),w[i]);
    42         dfs2(v,root);
    43     }
    44 }
    45 void init() {
    46     memset(head,0,sizeof(head));
    47     memset(f,0,sizeof(f));
    48     memset(deg,0,sizeof(deg));
    49     cnt=0;
    50 }
    51 int main() {
    52     int t;
    53     cin>>t;
    54     while(t--) {
    55         cin>>n;
    56         int x,y,w;
    57         init();
    58         for(int i=1; i<n; i++) {
    59             scanf("%d%d%d",&x,&y,&w);
    60             deg[x]++;
    61             deg[y]++;
    62             addEdge(x,y,w);
    63         }
    64         if(n==0||n==1) {
    65             cout<<0<<endl;
    66             continue;
    67         }
    68         int root=1;
    69         dfs1(root,0);
    70         f[root]=d[root];
    71         dfs2(root,0);
    72         int ans=0;
    73         for(int i=1; i<=n; i++)
    74             ans=max(ans,f[i]);
    75         cout<<ans<<endl;
    76     }
    77     return 0;
    78 }
    AC Code
  • 相关阅读:
    Microsoft Visual Studio 产品密钥
    ActiveReport 9手把手搭建环境及实战
    TFS 用户与组管理(转)
    FTS下载地址
    URLScan安装及配置(转)
    viewstate加密(转)
    .net 网站发布 Web.Config中的<compilation debug="true"/>
    WebDAV被启用(转)
    js字母大小写转换
    限制同一个用户在同一时间只能登陆一次(转)
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10726875.html
Copyright © 2011-2022 走看看