zoukankan      html  css  js  c++  java
  • HDU

    题意:给定一个带权边无向基环树,有两种操作,一种是改变某个边的权值,另一种是询问两点间的最短路径。

    可以对环进行缩点,以环为根建立一棵新树,并记录与环相连的所有点和环上的哪个点相连,将路径分为环外和环内的两类进行处理。环外的路径可以用树剖+树状数组维护,环内的路径复制一倍,用另一个树状数组维护。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int N=1e5+10;
      5 int hd[N],n,m,ne,sta[N],tp,vis[N],id[N],anc[N],lid[N],nl;
      6 int fa[N],son[N],siz[N],dep[N],top[N],bg[N],ed[N],rnk[N],tot;
      7 struct E2 {int u,v,c;} e2[N];
      8 struct E {int v,c,nxt;} e[N<<2];
      9 struct BIT {
     10     ll c[N<<1];
     11     int n;
     12     int lb(int x) {return x&-x;}
     13     void add(int u,int x) {for(; u<=n; u+=lb(u))c[u]+=x;}
     14     ll get(int u) {ll ret=0; for(; u; u-=lb(u))ret+=c[u]; return ret;}
     15     ll sum(int l,int r) {return get(r)-get(l-1);}
     16     void init(int _n) {memset(c,0,sizeof c),n=_n;}
     17 } tr1,tr2;
     18 void addedge(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
     19 bool isloop(int u) {return id[u]==n+1;}
     20 bool dfs_loop(int u,int f) {
     21     if(vis[u]) {
     22         while(!lid[u]) {
     23             int v=sta[tp--];
     24             id[v]=n+1,lid[v]=++nl;
     25         }
     26         return 1;
     27     }
     28     vis[u]=1,sta[++tp]=u;
     29     for(int i=hd[u]; ~i; i=e[i].nxt) {
     30         int v=e[i].v;
     31         if(v==f)continue;
     32         if(dfs_loop(v,u))return 1;
     33     }
     34     tp--;
     35     return 0;
     36 }
     37 void dfs_anc(int u,int f,int a) {
     38     anc[u]=a;
     39     for(int i=hd[u]; ~i; i=e[i].nxt) {
     40         int v=e[i].v;
     41         if(v==f||isloop(v))continue;
     42         dfs_anc(v,u,a);
     43     }
     44 }
     45 void dfs_chain_1(int u,int f,int d) {
     46     fa[u]=f,son[u]=0,siz[u]=1,dep[u]=d;
     47     for(int i=hd[u]; ~i; i=e[i].nxt) {
     48         int v=e[i].v;
     49         if(v==fa[u]||isloop(v))continue;
     50         dfs_chain_1(v,u,d+1),siz[u]+=siz[v];
     51         if(siz[v]>siz[son[u]])son[u]=v;
     52     }
     53 }
     54 void dfs_chain_2(int u,int tp) {
     55     top[u]=tp,bg[u]=++tot,rnk[bg[u]]=u;
     56     if(son[u])dfs_chain_2(son[u],tp);
     57     for(int i=hd[u]; ~i; i=e[i].nxt) {
     58         int v=e[i].v;
     59         if(v==fa[u]||v==son[u]||isloop(v))continue;
     60         dfs_chain_2(v,v);
     61     }
     62     ed[u]=tot;
     63 }
     64 void upd(int u,int v,int x) {
     65     if(isloop(u)&&isloop(v)) {
     66         int l=lid[u],r=lid[v];
     67         if(l>r)swap(l,r);
     68         if(r-l!=1)swap(l,r);
     69         tr2.add(r,-tr2.sum(r,r)),tr2.add(r+nl,-tr2.sum(r+nl,r+nl));
     70         tr2.add(r,x),tr2.add(r+nl,x);
     71     } else {
     72         int l=bg[id[u]],r=bg[id[v]];
     73         if(l>r)swap(l,r);
     74         tr1.add(r,-tr1.sum(r,r)),tr1.add(r,x);
     75     }
     76 }
     77 ll qry_loop(int u,int v) {
     78     int l=lid[u],r=lid[v];
     79     if(l>r)swap(l,r);
     80     return min(tr2.sum(l+1,r),tr2.sum(r+1,l+nl));
     81 }
     82 ll qry_tree(int u,int v) {
     83     int ancu=anc[u],ancv=anc[v];
     84     u=id[u],v=id[v];
     85     ll ret=0;
     86     for(; top[u]!=top[v]; u=fa[top[u]]) {
     87         if(dep[top[u]]<dep[top[v]])swap(u,v);
     88         ret+=tr1.sum(bg[top[u]],bg[u]);
     89     }
     90     if(dep[u]<dep[v])swap(u,v);
     91     ret+=tr1.sum(bg[v]+1,bg[u]);
     92     ret+=qry_loop(ancu,ancv);
     93     return ret;
     94 }
     95 int main() {
     96     int T;
     97     for(scanf("%d",&T); T--;) {
     98         memset(hd,-1,sizeof hd),ne=tp=nl=tot=0;
     99         memset(vis,0,sizeof vis);
    100         scanf("%d%d",&n,&m);
    101         for(int i=1; i<=n; ++i) {
    102             int u,v,c;
    103             scanf("%d%d%d",&u,&v,&c);
    104             addedge(u,v,c),addedge(v,u,c);
    105             e2[i]= {u,v,c};
    106         }
    107         for(int i=1; i<=n; ++i)id[i]=i;
    108         dfs_loop(1,0),id[n+1]=n+1;
    109         for(int u=1; u<=n; ++u)if(isloop(u))dfs_anc(u,0,u);
    110         for(int u=1; u<=n; ++u)if(isloop(u)) {
    111                 for(int i=hd[u]; ~i; i=e[i].nxt) {
    112                     int v=e[i].v;
    113                     if(!isloop(v))addedge(n+1,v,e[i].c);
    114                 }
    115             }
    116         dfs_chain_1(n+1,0,1),dfs_chain_2(n+1,n+1);
    117         tr1.init(tot),tr2.init(nl*2);
    118         for(int i=1; i<=n; ++i)upd(e2[i].u,e2[i].v,e2[i].c);
    119         while(m--) {
    120             int f,a,b;
    121             scanf("%d%d%d",&f,&a,&b);
    122             if(f==0)upd(e2[a].u,e2[a].v,b);
    123             else printf("%lld
    ",qry_tree(a,b));
    124         }
    125     }
    126     return 0;
    127 }

    也可以LCA+差分维护每个点到根节点的距离,复杂度少了个log(但实际速度差不了多少)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int N=1e5+10;
      5 int hd[N],n,m,ne,sta[N],tp,vis[N],id[N],anc[N],lid[N],nl;
      6 int fa[N],son[N],siz[N],dep[N],top[N],bg[N],ed[N],rnk[N],tot;
      7 struct E2 {int u,v,c;} e2[N];
      8 struct E {int v,c,nxt;} e[N<<2];
      9 struct BIT {
     10     ll c[N<<1];
     11     int n;
     12     int lb(int x) {return x&-x;}
     13     void add(int u,int x) {for(; u<=n; u+=lb(u))c[u]+=x;}
     14     ll get(int u) {ll ret=0; for(; u; u-=lb(u))ret+=c[u]; return ret;}
     15     ll sum(int l,int r) {return get(r)-get(l-1);}
     16     void init(int _n) {memset(c,0,sizeof c),n=_n;}
     17 } tr1,tr2;
     18 void addedge(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
     19 bool isloop(int u) {return id[u]==n+1;}
     20 bool dfs_loop(int u,int f) {
     21     if(vis[u]) {
     22         while(!lid[u]) {
     23             int v=sta[tp--];
     24             id[v]=n+1,lid[v]=++nl;
     25         }
     26         return 1;
     27     }
     28     vis[u]=1,sta[++tp]=u;
     29     for(int i=hd[u]; ~i; i=e[i].nxt) {
     30         int v=e[i].v;
     31         if(v==f)continue;
     32         if(dfs_loop(v,u))return 1;
     33     }
     34     tp--;
     35     return 0;
     36 }
     37 void dfs_anc(int u,int f,int a) {
     38     anc[u]=a;
     39     for(int i=hd[u]; ~i; i=e[i].nxt) {
     40         int v=e[i].v;
     41         if(v==f||isloop(v))continue;
     42         dfs_anc(v,u,a);
     43     }
     44 }
     45 void dfs_chain_1(int u,int f,int d) {
     46     fa[u]=f,son[u]=0,siz[u]=1,dep[u]=d;
     47     for(int i=hd[u]; ~i; i=e[i].nxt) {
     48         int v=e[i].v;
     49         if(v==fa[u]||isloop(v))continue;
     50         dfs_chain_1(v,u,d+1),siz[u]+=siz[v];
     51         if(siz[v]>siz[son[u]])son[u]=v;
     52     }
     53 }
     54 void dfs_chain_2(int u,int tp) {
     55     top[u]=tp,bg[u]=++tot,rnk[bg[u]]=u;
     56     if(son[u])dfs_chain_2(son[u],tp);
     57     for(int i=hd[u]; ~i; i=e[i].nxt) {
     58         int v=e[i].v;
     59         if(v==fa[u]||v==son[u]||isloop(v))continue;
     60         dfs_chain_2(v,v);
     61     }
     62     ed[u]=tot;
     63 }
     64 void upd(int u,int v,int x) {
     65     if(isloop(u)&&isloop(v)) {
     66         int l=lid[u],r=lid[v];
     67         if(l>r)swap(l,r);
     68         if(r-l!=1)swap(l,r);
     69         tr2.add(r,x),tr2.add(r+nl,x);
     70     } else {
     71         u=id[u],v=id[v];
     72         if(fa[u]==v)swap(u,v);
     73         tr1.add(bg[v],x),tr1.add(ed[v]+1,-x);
     74     }
     75 }
     76 ll qry_loop(int u,int v) {
     77     int l=lid[u],r=lid[v];
     78     if(l>r)swap(l,r);
     79     return min(tr2.sum(l+1,r),tr2.sum(r+1,l+nl));
     80 }
     81 ll qry_tree(int u,int v) {
     82     int ancu=anc[u],ancv=anc[v];
     83     u=id[u],v=id[v];
     84     ll ret=tr1.get(bg[u])+tr1.get(bg[v]);
     85     for(; top[u]!=top[v]; u=fa[top[u]])
     86         if(dep[top[u]]<dep[top[v]])swap(u,v);
     87     if(dep[u]<dep[v])swap(u,v);
     88     ret-=2*tr1.get(bg[v]);
     89     ret+=qry_loop(ancu,ancv);
     90     return ret;
     91 }
     92 int main() {
     93     int T;
     94     for(scanf("%d",&T); T--;) {
     95         memset(hd,-1,sizeof hd),ne=tp=nl=tot=0;
     96         memset(vis,0,sizeof vis);
     97         scanf("%d%d",&n,&m);
     98         for(int i=1; i<=n; ++i) {
     99             int u,v,c;
    100             scanf("%d%d%d",&u,&v,&c);
    101             addedge(u,v,c),addedge(v,u,c);
    102             e2[i]= {u,v,c};
    103         }
    104         for(int i=1; i<=n; ++i)id[i]=i;
    105         dfs_loop(1,0),id[n+1]=n+1;
    106         for(int u=1; u<=n; ++u)if(isloop(u))dfs_anc(u,0,u);
    107         for(int u=1; u<=n; ++u)if(isloop(u)) {
    108                 for(int i=hd[u]; ~i; i=e[i].nxt) {
    109                     int v=e[i].v;
    110                     if(!isloop(v))addedge(n+1,v,e[i].c);
    111                 }
    112             }
    113         dfs_chain_1(n+1,0,1),dfs_chain_2(n+1,n+1);
    114         tr1.init(tot),tr2.init(nl*2);
    115         for(int i=1; i<=n; ++i)upd(e2[i].u,e2[i].v,e2[i].c);
    116         while(m--) {
    117             int f,a,b;
    118             scanf("%d%d%d",&f,&a,&b);
    119             if(f==0)upd(e2[a].u,e2[a].v,b-e2[a].c),e2[a].c=b;
    120             else printf("%lld
    ",qry_tree(a,b));
    121         }
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结v2
    JS设置cookie、读取cookie、删除cookie
    Atitit 图像处理30大经典算法attilax总结
    Atitit数据库层次架构表与知识点 attilax 总结
    Atitit 游戏的通常流程 attilax 总结 基于cocos2d api
    Atitti css transition Animation differ区别
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
    Atitit 全屏模式的cs桌面客户端软件gui h5解决方案 Kiosk模式
    Atitit 混合叠加俩张图片的处理 图像处理解决方案 javafx blend
    Atitit  rgb yuv  hsv HSL 模式和 HSV(HSB) 图像色彩空间的区别
  • 原文地址:https://www.cnblogs.com/asdfsag/p/11285599.html
Copyright © 2011-2022 走看看