zoukankan      html  css  js  c++  java
  • ZOJ 3527

    这题难在破环。

    对于不是环的情况,只需按照一般的树形DP来做,一步一步往根递推就可以了。对于环,则枚举其中一点的两种情况,取或不取,然后再递推,就可以了。当到达某结点的下一结点为环开始的点时,退出即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int MAX=210010;
     7 
     8 int fr[MAX],next[MAX],ch[MAX];
     9 int N,qt[MAX],top,in[MAX];
    10 long long dp[MAX][2],dp1[MAX][2];
    11 bool flag[MAX];
    12 
    13 long long maxt(long long a,long long b){
    14     if(a>b)return a;
    15     return b;
    16 }
    17 
    18 long long dfs(int f,int u,long long d[][2], bool choice){
    19     while(true){
    20         int v=next[u];
    21         if(choice) flag[v]=flag[u]=true;
    22         if(v==f) break;
    23         d[v][0]+=maxt(d[u][0],d[u][1]);
    24         d[v][1]+=maxt(d[u][0],d[u][1]+ch[u]);
    25         u=v;
    26     }
    27     if(choice){
    28         return maxt(d[u][0],d[u][1]+ch[u]);
    29     }
    30     else{
    31         return maxt(d[u][0],d[u][1]);
    32     }
    33 }
    34 
    35 long long sech(int f){
    36     int u=next[f];
    37     dp1[u][0]+=dp[f][0];
    38     dp1[u][1]+=dp[f][0];
    39     long long res1=dfs(f,u,dp1,false);
    40     dp[u][0]+=dp[f][1];
    41     dp[u][1]+=(dp[f][1]+ch[f]);
    42     long long res2=dfs(f,u,dp,true);
    43     return maxt(res1,res2);
    44 }
    45 
    46 int main(){
    47     while(scanf("%d",&N)!=EOF){
    48         top=0;
    49         memset(in,0,sizeof(in));
    50         memset(flag,false,sizeof(flag));
    51         for(int i=1;i<=N;i++){
    52             scanf("%d%d%d",&fr[i],&ch[i],&next[i]);
    53             in[next[i]]++;
    54             dp[i][0]=0;dp[i][1]=fr[i];
    55         }
    56         for(int i=1;i<=N;i++)
    57         if(in[i]==0)
    58         qt[++top]=i;
    59         while(top!=0){
    60             int u=qt[top--];
    61             int v=next[u];
    62             flag[u]=true;
    63             dp[v][1]+=maxt(dp[u][0],dp[u][1]+ch[u]);
    64             dp[v][0]+=maxt(dp[u][0],dp[u][1]);
    65             in[v]--;
    66             if(in[v]==0)
    67             qt[++top]=v;
    68         }
    69         long long sumt=0;
    70         memcpy(dp1,dp,sizeof(dp));
    71         for(int i=1;i<=N;i++){
    72             if(!flag[i]){
    73                 sumt+=sech(i);
    74             }
    75         }
    76         printf("%lld
    ",sumt);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    python---装饰器用法小结
    python---mysql事务
    python---sql语句集体更改数据
    python多继承中的深度优先与广度优先
    python---copy
    vue 主次页面区分
    css 过渡动画
    android web外壳
    cordova 打包 守护进程无法启动
    JavaScript 原生控制元素添加删除
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3850911.html
Copyright © 2011-2022 走看看