POJ3585 Accumulation Degree(二次扫描与换根法)
题目:http://poj.org/problem?id=3585
很容易想出暴力。那么就先扫一遍。
然后得到了指定一个根后每个点的子树值。
怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前点的其他子树值 ” 就好了。
发现只需要把父亲的值减去 min ( 当前子树的值,该点与父亲间的边的值 ) 就行了!(因为当初这样加过)
需要注意一下的是叶节点。赋成INF或边的值都行。
特别需要注意的是第一次选的根节点在其余时候是叶节点的情况!!!!!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int T,n,xnt,head[],rd[],x,y,z,yt;
const int INF=;
long long d[],ans;
struct Node{
int next,to;
long long w;
}edge[];
void add(int x,int y,int z)
{
edge[++xnt].next=head[x];
edge[xnt].to=y;
edge[xnt].w=z;
head[x]=xnt;
rd[x]++;
}
void dfs1(int k,int fa)
{
if(rd[k]==&&k!=yt)
{
d[k]=INF;
return;
}
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa)continue;
dfs1(v,k);
d[k]+=min(d[v],edge[i].w);
// printf("1 k=%d d=%lld\n",k,d[k]);
}
}
void dfs2(int k,int fa,int u)
{
long long r=d[fa]-min(d[k],edge[u].w);
if(rd[fa]==)r=edge[u].w;///////////////当根节点也是叶节点时!很特殊
if(rd[k]==)
{
d[k]=min(r,edge[u].w);
return;
}
d[k]+=min(r,edge[u].w);
// printf("2 k=%d d=%lld\n",k,d[k]);
for(int i=head[k];i;i=edge[i].next)
{
if(edge[i].to==fa)continue;
dfs2(edge[i].to,k,i);
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(head,,sizeof head);
memset(d,,sizeof d);
memset(rd,,sizeof rd);
xnt=;ans=-;///////
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
yt=;
dfs1(,);
for(int i=head[];i;i=edge[i].next)
dfs2(edge[i].to,,i);
for(int i=;i<=n;i++)ans=max(ans,d[i]);
printf("%lld\n",ans);
}
return ;
}
POJ3585 Accumulation Degree(二次扫描与换根法)的更多相关文章
- 【POJ3585】Accumulation Degree 二次扫描与换根法
简单来说,这是一道树形结构上的最大流问题. 朴素的解法是可以以每个节点为源点,单独进行一次dp,时间复杂度是\(O(n^2)\) 但是在朴素求解的过程中,相当于每次都求解了一次整棵树的信息,会做了不少 ...
- poj3585 树形dp 二次扫描,换根法模板题
#include<iostream> #include<cstring> #include<cstdio> #include<vector> using ...
- 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)
写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...
- poj 3585 Accumulation Degree(二次扫描和换根法)
Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- 【51Nod1405】树上距离和 二次扫描与换根法
题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和. 题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小.树上前缀和.第二遍 dfs 遍 ...
- poj - 3585(二次扫描与换根法)
周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...
- [LuoguP1829]Crash的文明表格(二次扫描与换根+第二类斯特林数)
Solution: 由于 \[ x^m = \sum_{i=0}^m{~m~\choose i}{~x~\brace i}i! \] 将所求的式子化成这样,挖掘其性质,考虑是否能从儿子转移(或 ...
- poj3585 Accumulation Degree【树形DP】【最大流】
Accumulation Degree Time Limit: 5000MS Memory Limit: 65536K Total Submissions:3151 Accepted: 783 ...
随机推荐
- 管道的创建与读写pipe
1.管道的创建 #include <unistd.h> int pipe(int pipefd[2]); linux下创建管道可以通过函数pipe来完成.该函数如果调用成功,数组中将包含两 ...
- 文件的移动,删除 rename remove unlink 函数
int rename(const char *oldpath, const char *newpath); rename() renames a file, moving it between ...
- JdbcTemplate.queryForObject
} catch (EmptyResultDataAccessException e) { log.info(">>>检测到有无记录>>>>" ...
- UVALive 5881
DES:给出一个数列.然后有q个询问,对给定的区间内是否有重复的数.如果有输出任意一个重复的.如果没有输出OK. 开始以为是线段树.后来发现.只是水的比较隐蔽.感觉这个方法还是很聪明的.把每个点的最近 ...
- 关于双网卡双宽带Http及Socks代理的配置
1.[硬件环境] a, 1台宿主(win7)+几十台虚拟机(xp)(vm10的版本,估计可打开52台以上的虚拟机) b, 双网卡,其中一个网卡通过路由连接电信ADSL,一个直连集线器,可直接连接移动m ...
- C++primer 练习4.31-4.35
Exercise 4.31: 编写程序从标准输入设备读入字符串,并把该串存放在字 符数组中.描述你的程序如何处理可变长的输入.提供比 你分配的数组长度长的字符串数据测试你的程序. string in_ ...
- 使用Mockito时遇到的一些问题
最近在使用Mockito时遇到了几个比较tricking的问题,在这里记录一下. 1.如果方法的参数或者返回类型是泛型通配符相关的(如<?>,<? extends XXX>), ...
- 接收一条音频(系统音频)彩信,点菜单键选择View slideshow,不能播放,提示是否导入vCard
[前提条件]: [操作步骤]:接收一条音频(系统音频,格式为ogg),点菜单键选择View slideshow [测试结果]:不能播放,提示是否导入vCard [预期结果]:可以播放 [备注]:附lo ...
- DialogFragment详解
详解一: Android提供alert.prompt.pick-list,单选.多选,progress.time-picker和date-picker对话框,并提供自定义的dialog.在Androi ...
- C语言基础总结 分类: iOS学习 c语言基础 2015-06-11 10:08 23人阅读 评论(0) 收藏
//欲练此功必先自宫!!! //第一天:C语言的基础 //进制 //2进制, 10进制, 8进制, 16进制 //注:8进制数前加0, 16进制数前加0x ...