首页 > 代码库 > ZOJ 3527
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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。