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\n",sumt);
77     }
78     return 0;
79 }
View Code
posted @ 2014-07-17 14:02  chenjunjie1994  阅读(273)  评论(0编辑  收藏  举报