首页 > 代码库 > BZOJ 1060 ZJOI2007 时态同步 树形DP
BZOJ 1060 ZJOI2007 时态同步 树形DP
题目大意:给定一棵有根树,每次操作可以使某条边边权+1,求最少的操作次数,使根节点到每一个叶节点的距离都相等
树形DP
容易发现操作对于越靠近根节点的边进行越有利
首先对于每个节点扫一遍记录这个节点到子树中所有叶节点的最大距离 然后枚举每一个儿子 将该节点和该儿子之间的边权补至最大距离相等
对于每个节点都如此做 最后就能保证根节点到每个叶节点的距离都相等
数据有误坑死人……
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 using namespace std; struct abcd{ int to,f,next; }table[M<<1]; int head[M],tot; int n,root; long long ans; int max_distance[M];//由于标程有误没开long long,因此这个变量如果开成long long的话最后3个点会WA掉, void Add(int x,int y,int z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void DFS(int x,int from) { int i; for(i=head[x];i;i=table[i].next) { if(table[i].to==from) continue; DFS(table[i].to,x); max_distance[x]=max(max_distance[x],max_distance[table[i].to]+table[i].f); } for(i=head[x];i;i=table[i].next) { if(table[i].to==from) continue; ans+=max_distance[x]-table[i].f-max_distance[table[i].to]; } } int main() { int i,x,y,z; cin>>n>>root; for(i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),Add(x,y,z),Add(y,x,z); DFS(root,0); cout<<ans<<endl; }
BZOJ 1060 ZJOI2007 时态同步 树形DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。