zoukankan      html  css  js  c++  java
  • 10.24T2 树链剖分

    2.盟主的忧虑

     (worry)

    【问题描述】

        江湖由 N 个门派(2≤N≤100,000,编号从 1 到 N)组成,这些门派之间有 N-1 条小道将他们连接起来,每条道路都以“尺”为单位去计量,武林盟主发现任何两个门派都能够直接或者间接通过小道连接。
        虽然整个江湖是可以互相到达的,但是他担心有心怀不轨之徒破坏这个武林的安定,破坏小道,于是武林盟主又秘密地修建了 M 条密道(1≤M≤100,000),但每条小道距离都不超过10亿尺。
        果不其然,最近一个名叫“太吾”的组织意欲破坏武林的小道,请你帮盟主想想办法,如果门派 A 到门派 B 的直连小道被破坏,从 A 走到 B 的所有路径中,经过密道的距离最少是多少? 
     

    【输入】

    第一行数字 N M
    接下来 N-1 行,每行两个整数 A B,表示 A-B 间有一条直连小道
    接下来 M 行,每行三个数字 A B V,表示 A-B 间有一条代价为 V 的密道

    【输出】

     输出 N-1 行,对应原输入的小道,每个小道被破坏后,最少需要经过多长的密道?如果不存在替换的道路,请输出-1
     

    【样例输入】

    6 3

    4 1

    1 3

    4 5

    1 2

    6 5

    3 6 8

    2 3 7

    6 4 5

    【样例输出】

    8

    7

    5

    7

    5

    【数据范围与约定】

    30%数据:N<=300,M<=1000
    50%数据:N<=1000,M<=1000
    70%数据:N<=5000,M<=5000
    对于另外15%的数据点:树是一条链
    100%数据:N,M<=100,000

    一条密道影响的是连接两点之间的简单路径,所以我们就可以用树链剖分覆盖两点之间的边,维护一下最小值就可以了,查询的时候所有边打包在一起查询就完成了

    此题需要扩栈

    code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #define lc (p<<1)
      6 #define rc (p<<1|1)
      7 #define N 1000006
      8 using namespace std;
      9 const long long inf=99999999999;
     10 struct node{
     11     long long u,v,w;
     12 }e[N];
     13 struct NODE{
     14     int a,b,c;
     15 }q[N];
     16 bool cmp(const NODE&a,const NODE&b){
     17     return a.c>b.c;
     18 }
     19 long long first[N],nxt[N],cnt,Ans[N];
     20 void add(long long u,long long v,long long w){
     21     e[++cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].w=w;
     24     nxt[cnt]=first[u];
     25     first[u]=cnt;
     26 }
     27 struct T{
     28     long long l,r,lazy;
     29 }t[N];
     30 void pushnow(long long p,long long v){
     31     t[p].lazy=v;
     32 }
     33 void pushdown(long long p){
     34     if(t[p].lazy!=-1){
     35         pushnow(lc,t[p].lazy);
     36         pushnow(rc,t[p].lazy);
     37         t[p].lazy=-1;
     38     }
     39 }
     40 void build(long long p,long long l,long long r){
     41     t[p].l=l,t[p].r=r;t[p].lazy=-1;
     42     if(l==r)return;
     43     long long mid=l+r>>1;
     44     build(lc,l,mid);
     45     build(rc,mid+1,r);
     46 }
     47 void update(long long p,long long ql,long long qr,long long v){
     48     if(ql<=t[p].l&&t[p].r<=qr){
     49         pushnow(p,v);
     50         return;
     51     }
     52     pushdown(p);
     53     long long mid=t[p].l+t[p].r>>1;
     54     if(ql<=mid)update(lc,ql,qr,v);
     55     if(qr>mid)update(rc,ql,qr,v);
     56 }
     57 long long siz[N],hson[N],dep[N],top[N],num[N],pre[N],tot,fa[N];
     58 void Count(long long p){
     59     if(t[p].l==t[p].r){
     60         Ans[pre[t[p].l]]=t[p].lazy;
     61         return;
     62     }
     63     pushdown(p);
     64     Count(lc);
     65     Count(rc);
     66 }
     67 void dfs1(long long x,long long father){
     68     siz[x]=1,hson[x]=0;fa[x]=father;
     69     for(long long i=first[x];i;i=nxt[i]){
     70         long long v=e[i].v;
     71         if(v==father)continue;
     72         dep[v]=dep[x]+1;
     73         dfs1(v,x);
     74         siz[x]+=siz[v];
     75         if(!hson[x]||siz[hson[x]]<siz[v])hson[x]=v;
     76     }
     77 }
     78 void dfs2(long long x,long long tp,long long father){
     79     top[x]=tp;
     80     pre[num[x]=++tot]=x;
     81     if(hson[x])dfs2(hson[x],tp,x);
     82     for(long long i=first[x];i;i=nxt[i]){
     83         long long v=e[i].v;
     84         if(v==father)continue;
     85         if(v==hson[x])continue;
     86         dfs2(v,v,x);
     87     }
     88 }
     89 long long modify(long long x,long long y,long long v){
     90     while(top[x]!=top[y]){
     91         if(dep[top[y]]>dep[top[x]])swap(x,y);
     92         update(1,num[top[x]],num[x],v);
     93         x=fa[top[x]];
     94     }
     95     if(dep[x]<dep[y])swap(x,y);
     96     if(num[y]+1<=num[x])update(1,num[y]+1,num[x],v);
     97 }
     98 int main(){
     99     int siz=100<<20;//40M
    100     __asm__("movl %0,%%esp
    "::"r"((char*)malloc(siz)+siz));//windows用这个
    101     //__asm__("movq %0,%%rsp
    "::"r"((char*)malloc(siz)+siz));//linux用这个
    102     long long n,m;
    103     cin>>n>>m;
    104     for(long long i=1;i<n;i++){
    105         long long u,v;
    106         cin>>u>>v;
    107         add(u,v,0);
    108         add(v,u,0);
    109     }
    110     fa[1]=1;
    111     dfs1(1,1);
    112     dfs2(1,1,1);
    113     build(1,1,tot);
    114     for(long long i=1;i<=m;i++){
    115         cin>>q[i].a>>q[i].b>>q[i].c;
    116     }
    117     sort(q+1,q+m+1,cmp);
    118     for(int i=1;i<=m;i++){
    119         modify(q[i].a,q[i].b,q[i].c);
    120     }
    121     Count(1);
    122     for(long long i=1;i<=cnt;i+=2){
    123         long long u=e[i].u,v=e[i].v;
    124         if(fa[v]==u)swap(u,v);
    125         printf("%d
    ",Ans[u]);
    126     }
    127     exit(0);
    128     return 0;
    129 }

    over

  • 相关阅读:
    程序编译的四个阶段
    c++的符号表的肤浅认识
    git高级用法之cheery-pick
    rust 使用国内镜像,快速安装方法
    protobuf 的enum与string转换
    c++ 获取GMT 时间和字符串
    proto3 不支持内建类型的非空判断即 hasXXX
    cmake 中的 compile_commands.json 文件
    整数划分问题(记忆化搜索和DP方法)
    查找系列合集-二分查找
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9846045.html
Copyright © 2011-2022 走看看