zoukankan      html  css  js  c++  java
  • Acwing 287.积蓄程度 (树形DP换根)

    题目

    有一个树形的水系,由 N-1 条河道和 N 个交叉点组成。

    我们可以把交叉点看作树中的节点,编号为 1~N,河道则看作树中的无向边。

    每条河道都有一个容量,连接 x 与 y 的河道的容量记为 c(x,y)。

    河道中单位时间流过的水量不能超过河道的容量。

    有一个节点是整个水系的发源地,可以源源不断地流出水,我们称之为源点。

    除了源点之外,树中所有度数为 1 的节点都是入海口,可以吸收无限多的水,我们称之为汇点。

    也就是说,水系中的水从源点出发,沿着每条河道,最终流向各个汇点。

    在整个水系稳定时,每条河道中的水都以单位时间固定的水量流向固定的方向。

    除源点和汇点之外,其余各点不贮存水,也就是流入该点的河道水量之和等于从该点流出的河道水量之和。

    整个水系的流量就定义为源点单位时间发出的水量。

    在流量不超过河道容量的前提下,求哪个点作为源点时,整个水系的流量最大,输出这个最大值。

    输入格式
    输入第一行包含整数T,表示共有T组测试数据。

    每组测试数据,第一行包含整数N。

    接下来N-1行,每行包含三个整数x,y,z,表示x,y之间存在河道,且河道容量为z。

    节点编号从1开始。

    输出格式
    每组数据输出一个结果,每个结果占一行。

    数据保证结果不超过231−1。

    数据范围
    N≤2∗105
    输入样例:
    1
    5
    1 2 11
    1 4 13
    3 4 5
    4 5 10
    输出样例:
    26

    思路

    这道题目有点像最大流,这题我们采用树形dp进行换根,因为他要求可能的最大水流,那么如果我们以每个点为根暴力显然超时,所以我们只需要刚开始以一个点为根求出每个点往下的最大流,然后从上往下在dfs一遍,进行dp换根。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=0;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<int ,int> PII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f = -1;
            ch=getchar();
        } 
        while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }   return x*f;
    }
    
    const int maxn=2e5+5;
    vector <PII> G[maxn];
    int n;
    int ans;
    int d[maxn];
    int f[maxn];
    int deg[maxn];
    
    int dfs_d (int u,int fa) {
          if (deg[u]==1) {
              d[u]=inf;
              return d[u];
          }
          d[u]=0;
          for (auto it:G[u]) {
              int j=it.first;
              if (j==fa) continue;
              d[u]+=min (dfs_d (j,u),it.second);
          }
          return d[u];
    }
    
    void dfs_f (int u,int fa) {
       for (auto it:G[u]) {
           int j=it.first;
           if (j==fa) continue;
           if (deg[j]==1) f[j]=min (f[u]-it.second,it.second);
           else {
               f[j]=d[j]+min (f[u]-min (it.second,d[j]),it.second);
               dfs_f (j,u);
           }
       }
    }
    
    int main () {
       ios::sync_with_stdio (false);
       int t;
       cin>>t;
       while (t--) {
            scanf ("%d",&n);
            int temp,flag=0;
            rep (i,1,n) G[i].clear ();
            MT (deg,0);
            rep (i,1,n-1) {
               int a,b,c;
               a=read (), b=read (),c=read ();
               G[a].pb (mp (b,c));
               if (!flag) {
                   temp=c;
                   flag=1;
               }
               G[b].pb (mp (a,c));
               deg[a]++,deg[b]++;
            }
           
           int root=1;
           while (root<=n&&deg[root]==1) root++;
           if (root>n) {
               cout<<temp<<endl;
               continue;
           }
    
           dfs_d (root,-1);
           f[root]=d[root];
           dfs_f (root,-1);
    
           ans=0;
           rep (i,1,n) ans=max (ans,f[i]);
           printf ("%d
    ",ans);
       }
       return 0;
    }
    
    
  • 相关阅读:
    BZOJ 3132: 上帝造题的七分钟 树状数组+差分
    PAT Advanced 1006 Sign In and Sign Out (25 分)
    PAT Advanced 1011 World Cup Betting (20 分)
    PAT Basic 1032 挖掘机技术哪家强 (20 分)
    PAT Basic 1028 人口普查 (20 分)
    PAT Basic 1004 成绩排名 (20 分)
    大数据数据库HBase(二)——搭建与JavaAPI
    PAT Advanced 1009 Product of Polynomials (25 分)(vector删除元素用的是erase)
    PAT Advanced 1002 A+B for Polynomials (25 分)(隐藏条件,多项式的系数不能为0)
    PAT Basic 1041 考试座位号 (15 分)
  • 原文地址:https://www.cnblogs.com/hhlya/p/13452054.html
Copyright © 2011-2022 走看看