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; }
相关文章推荐
- 洛谷 P1131 [ZJOI2007]时态同步
- 洛谷 P1131 BZOJ 1060 [ZJOI2007]时态同步
- 洛谷 P1131 [ZJOI2007]时态同步
- 洛谷 P1131 [ZJOI2007]时态同步
- 洛谷P1131 [ZJOI2007]时态同步
- P1131 [ZJOI2007]时态同步
- P1131 [ZJOI2007]时态同步
- 【洛谷1131】【ZJOI2007】时态同步
- 【洛谷1131】【ZJOI2007】时态同步
- P1131 [ZJOI2007]时态同步
- bzoj1060 [ZJOI2007]时态同步
- P1131 [ZJOI2007]时态同步
- BZOJ1060:[ZJOI2007]时态同步——题解
- 【洛谷】[ZJOI2007]时态同步-树形DP
- 【bzoj1060】[ZJOI2007]时态同步 树形dp
- bzoj千题计划163:bzoj1060: [ZJOI2007]时态同步
- bzoj1060: [ZJOI2007]时态同步
- 1060: [ZJOI2007]时态同步
- BZOJ 1060: [ZJOI2007]时态同步( 树形dp )
- 【BZOJ】1060: [ZJOI2007]时态同步