ZOJ 3527
2024-08-31 05:41:37
这题难在破环。
对于不是环的情况,只需按照一般的树形DP来做,一步一步往根递推就可以了。对于环,则枚举其中一点的两种情况,取或不取,然后再递推,就可以了。当到达某结点的下一结点为环开始的点时,退出即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX=; int fr[MAX],next[MAX],ch[MAX];
int N,qt[MAX],top,in[MAX];
long long dp[MAX][],dp1[MAX][];
bool flag[MAX]; long long maxt(long long a,long long b){
if(a>b)return a;
return b;
} long long dfs(int f,int u,long long d[][], bool choice){
while(true){
int v=next[u];
if(choice) flag[v]=flag[u]=true;
if(v==f) break;
d[v][]+=maxt(d[u][],d[u][]);
d[v][]+=maxt(d[u][],d[u][]+ch[u]);
u=v;
}
if(choice){
return maxt(d[u][],d[u][]+ch[u]);
}
else{
return maxt(d[u][],d[u][]);
}
} long long sech(int f){
int u=next[f];
dp1[u][]+=dp[f][];
dp1[u][]+=dp[f][];
long long res1=dfs(f,u,dp1,false);
dp[u][]+=dp[f][];
dp[u][]+=(dp[f][]+ch[f]);
long long res2=dfs(f,u,dp,true);
return maxt(res1,res2);
} int main(){
while(scanf("%d",&N)!=EOF){
top=;
memset(in,,sizeof(in));
memset(flag,false,sizeof(flag));
for(int i=;i<=N;i++){
scanf("%d%d%d",&fr[i],&ch[i],&next[i]);
in[next[i]]++;
dp[i][]=;dp[i][]=fr[i];
}
for(int i=;i<=N;i++)
if(in[i]==)
qt[++top]=i;
while(top!=){
int u=qt[top--];
int v=next[u];
flag[u]=true;
dp[v][]+=maxt(dp[u][],dp[u][]+ch[u]);
dp[v][]+=maxt(dp[u][],dp[u][]);
in[v]--;
if(in[v]==)
qt[++top]=v;
}
long long sumt=;
memcpy(dp1,dp,sizeof(dp));
for(int i=;i<=N;i++){
if(!flag[i]){
sumt+=sech(i);
}
}
printf("%lld\n",sumt);
}
return ;
}
最新文章
- python爬虫实战(一)——实时获取代理ip
- 【HOW】SharePoint如何彻底删除用户
- PHP常用功能
- Java虚拟机4:内存溢出
- Composite模式
- Hadoop学习10--常用命令记录帖
- easyui datagrid 列拖拽
- WordPress RokMicroNews插件‘thumb.php’ 多个安全漏洞
- jQuery慢慢啃之CSS(六)
- .net如何后台批量删除
- python应用部署--flask
- Makefile中的变量和shell变量
- 常用 SQL Server 规范集锦
- Yii2基本概念之——生命周期(LifeCycle)
- H5 实现图片上传预览
- Vue 快速入门
- Android向系统日历中添加日程事件
- ORACLE数据库数据的备份与恢复
- CSS之旋转立方体
- 修改Xcode工程名称