【动态规划】【树形DP】[BZOJ 1040]骑士
2015-07-15 10:44
381 查看
首先可以发现肯定这个图是一个森林,而且在这个森林之中只有一个环,那么只要找到这个环上的任意一条边(删掉这条边)然后对这条边的两个端点分别作两次最大独立集,然后分别取两个点中不取的情况的最大值,然后这个值就是要找的了,因为只有一个环,所以我找环的方法是用并查集的方法。。
[code]#include <cstdio> //#include <conio.h> #include <algorithm> #include <cstring> #include <vector> #include <iostream> #include <map> using namespace std; const int MAXN = 1000000; int w[MAXN+10]; vector<int> vec[MAXN+10]; int fat[MAXN+10]; inline int findfa(int u){ if(fat[u]) return findfa(fat[u]); return u; } pair<int, int> pos[MAXN+10]; int f1, f2, pcnt; void addedge(int u, int v){ f1=findfa(u); f2 = findfa(v); if(f1 == f2){ pos[++pcnt] = make_pair(u, v); return ; } fat[f1] = f2; vec[u].push_back(v); vec[v].push_back(u); } long long f[MAXN+10], g[MAXN+10]; void dp(int u, int fa){ f[u] = g[u] = 0; int Len = vec[u].size(); for(int i=0;i<Len;i++) if(vec[u][i]!=fa && vec[u][i]!=-1){ dp(vec[u][i], u); g[u] += 1LL * max(f[vec[u][i]], g[vec[u][i]]); f[u] += 1LL * g[vec[u][i]]; } f[u] += 1LL * w[u]; } int main(){ int n, v; long long ans = 0; scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d", &w[i]); scanf("%d", &v); addedge(i, v); } for(int i=1;i<=pcnt;i++){ dp(pos[i].first, -1); long long tmp = g[pos[i].first]; dp(pos[i].second, -1); ans += max(tmp, g[pos[i].second]); } cout<<ans<<endl; return 0; }
相关文章推荐
- iOS中视图控制器指定自定义UIView
- Linux报错-------ln: 无法创建符号链接"***": 只读文件系统
- POJ-1511(Invitation Cards )——spfa+邻接表
- java 去除空行程序 以及set接口的使用特征
- 图widget--jqplot样品和参数描述的简单演示
- VS编译wxWidgets
- 用soapUI做接口级别的功能和性能测试
- 托管代码 VS 非托管代码
- Bootstrap 模态框、轮播 结合使用
- 黑马程序员--IOS基础第三天(C语言)
- 基于Media Foundation获取音频视频输入设备列表
- 图像的灰度化以及二值图函数
- 百度PUSH PHP服务器端
- GNU Linux系统变量(sysctl配置命令)综合使用
- CSV格式转成libsvm标准格式的小程序
- web前端基础 什么是对象
- 聚类结果的评估指标及其JAVA实现
- Android 实现蘑菇街购物车动画效果
- 菜鸟vimer成长记——第2.0章、模式初探
- MVC授权不通过之后不执行任何自定义ActionFilter