您的位置:首页 > 其它

BZOJ1060: [ZJOI2007]时态同步(洛谷P1131)

2018-02-24 10:29 141 查看

贪心

BZOJ题目传送门

洛谷题目传送门

开学了。。。

为什么一坨树形DP啊。。。

设w[x]w[x]为以xx为根的子树中传到叶子节点所需时间的最大值。那么每次下传一个标记remrem表示当前已经在这条路径上加了多少时间,每遍历到一个节点时把答案加上w[rt]−w[x]−remw[rt]−w[x]−rem,然后把remrem更新为w[rt]−w[x]w[rt]−w[x]即可。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 500005
#define F inline
using namespace std;
typedef long long LL;
struct edge{ int next,to,dis; }ed[N<<1];
int n,k,rt,h
,fa
;
LL ans,w
,dis
;
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
F int _read(){
int x=0,f=1; char ch=readc();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=readc(); }
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x*f;
}
F void addedge(int x,int y,int z){
ed[++k]=(edge){h[x],y,z},h[x]=k;
}
void dfs(int x){
for (int i=h[x],v;i;i=ed[i].next)
if ((v=ed[i].to)!=fa[x]){
dis[v]=dis[x]+ed[i].dis,fa[v]=x;
dfs(v),w[x]=max(w[x],w[v]);
}
w[x]=max(w[x],dis[x]);
}
void dfs(int x,LL rem){
for (int i=h[x],v;i;i=ed[i].next)
if ((v=ed[i].to)!=fa[x])
ans+=w[rt]-w[v]-rem,dfs(v,w[rt]-w[v]);
}
int main(){
n=_read(),rt=_read();
for (int i=1,x,y,z;i<n;i++)
x=_read(),y=_read(),z=_read(),addedge(x,y,z),addedge(y,x,z);
return dfs(rt),dfs(rt,0),printf("%lld\n",ans),0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: