JZOJ5385. 【NOIP2017提高A组模拟9.23】Carry 树上倍增
2017-09-23 15:58
555 查看
题意:给你一棵树,q对点,要求每次从qx走到qy的花费为最大路径权值,可以把一条边减小L,问最少花费。
= =简单题,比赛的时候只是扫了一眼,觉得应该是树剖裸题,然后就放了= =
事实上也可以用树剖来做,但是非常复杂,难以维护。
倍增就好了,和那个次小生成树一样,维护一个每个点往上2^i的路径的最大次大权值。然后那个L的那个东西,我每次在求一对点的LCA过程中,直接用已经求出的最大次大维护,然后最后把最大边拉出来记录一下,最后把所有边扫一遍+不改边的贡献就ok。
= =简单题,比赛的时候只是扫了一眼,觉得应该是树剖裸题,然后就放了= =
事实上也可以用树剖来做,但是非常复杂,难以维护。
倍增就好了,和那个次小生成树一样,维护一个每个点往上2^i的路径的最大次大权值。然后那个L的那个东西,我每次在求一对点的LCA过程中,直接用已经求出的最大次大维护,然后最后把最大边拉出来记录一下,最后把所有边扫一遍+不改边的贡献就ok。
#include<cstdio> #include<algorithm> #include<cstring> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int N=1e5+5; const int inf=2e9; typedef long long ll; int n,m,q,l; int fa [22],head ,next ,go ,val ; int dep ; ll ans,sum ; int mx [22],mx2 [22]; int id [22],tot; inline void add(int x,int y,int z) { go[++tot]=y; next[tot]=head[x]; val[tot]=z; head[x]=tot; } inline void dfs(int x,int last,int y) { fa[x][0]=last,mx[x][0]=y; id[x][0]=x; dep[x]=dep[last]+1; fo(i,1,19) { fa[x][i]=fa[fa[x][i-1]][i-1]; if (mx[x][i-1]>mx[fa[x][i-1]][i-1]) { mx[x][i]=mx[x][i-1]; id[x][i]=id[x][i-1]; mx2[x][i]=max(mx2[x][i-1],mx[fa[x][i-1]][i-1]); } else { int fat=fa[x][i-1]; mx[x][i]=mx[fat][i-1]; id[x][i]=id[fat][i-1]; mx2[x][i]=max(mx2[fat][i-1],mx[x][i-1]); } } for(int i=head[x];i;i=next[i]) { int v=go[i]; if (v!=last) dfs(v,x,val[i]); } } inline void update(int x,int i,int& Mx,int& Mx2,int& Id) { if (mx[x][i]>Mx) { Mx2=max(Mx2,max(Mx,mx2[x][i])); Mx=mx[x][i]; Id=id[x][i]; } else Mx2=max(Mx2,mx[x][i]); } inline void mark(int mx,int mx2,int id) { ans+=mx; if (mx2==mx)return; sum[id]+=(mx-mx2<=l)?mx2-mx:-l; } inline void solve(int x,int y) { if (x==y)return ; int mx=-inf,mx2=-inf,id=0; if (dep[x]<dep[y])swap(x,y); if (dep[x]>dep[y]) fd(i,19,0)if (dep[fa[x][i]]>=dep[y]) { update(x,i,mx,mx2,id); x=fa[x][i]; } if (x==y) { mark(mx,mx2,id); return; } fd(i,19,0) { if (fa[x][i]!=fa[y][i]) { update(x,i,mx,mx2,id); update(y,i,mx,mx2,id); x=fa[x][i],y=fa[y][i]; } } update(x,0,mx,mx2,id); update(y,0,mx,mx2,id); mark(mx,mx2,id); } int main() { //freopen("carry.in","r",stdin); //freopen("carry.out","w",stdout); scanf("%d%d%d",&n,&q,&l); fo(i,1,n-1) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z);add(y,x,z); } dfs(1,0,0); fo(i,1,q) { int x,y; scanf("%d%d",&x,&y); solve(x,y); } ll mn=1e15; fo(i,1,n)mn=min(mn,sum[i]); printf("%lld\n",ans+mn); }
相关文章推荐
- JZOJ 5385. 【NOIP2017提高A组模拟9.23】Carry
- jzoj5385. 【NOIP2017提高A组模拟9.23】Carry
- JZOJ5385. 【NOIP2017提高A组模拟9.23】Carry
- JZOJ 5384. 【NOIP2017提高A组模拟9.23】四维世界
- jzoj5290 【NOIP2017提高组A组模拟8.17】行程的交集 (树上路径交,dfs序+树状数组维护姿势)
- JZOJ 5386. 【NOIP2017提高A组模拟9.23】碎
- JZOJ5394. 【NOIP2017提高A组模拟10.5】Ping 树上差分 树状数组
- JZOJ5384. 【NOIP2017提高A组模拟9.23】四维世界 组合数学
- jzoj5402 【NOIP2017提高A组模拟10.8】God Knows
- JZOJ 5185. 【NOIP2017提高组模拟6.30】tty's sequence
- [JZOJ5177]【NOIP2017提高组模拟6.28】TRAVEL
- JZOJ5248. 【NOIP2017提高A组模拟8.10】花花的聚会
- JZOJ5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- JZOJ 4921. 【NOIP2017提高组模拟12.10】幻魔皇
- 【JZOJ4932】【NOIP2017提高组模拟12.24】B
- 【jzoj5389】【NOIP2017提高A组模拟9.26】【解梦】
- JZOJ5390. 【NOIP2017提高A组模拟9.26】逗气
- 【jzoj5333】【NOIP2017提高A组模拟8.23】【大新闻】【可持久化线段树】
- 【JZOJ 5394】【NOIP2017提高A组模拟10.5】Ping
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology