zoukankan      html  css  js  c++  java
  • poj2763

    题解:

    和spoj375 差不多,只是最大值改成了总和

    代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=400005;
    int data[N],p[N],n,s,m,ans,pos,fp[N],num[N];
    int x,y,z,tot,top[N],T,e[N][3],val[N],deep[N],son[N],fa[N],ne[N],fi[N],zz[N];
    void jb(int x,int y)
    {
        ne[++tot]=fi[x];
        fi[x]=tot;
        zz[tot]=y;
    }
    void dfs1(int x,int y,int z)
    {
        deep[x]=z;
        fa[x]=y;
        num[x]=1;
        for (int i=fi[x];i;i=ne[i])
         {
             int k=zz[i];
             if (k!=y)
              {
                  dfs1(k,x,z+1);
                  num[x]+=num[k];
                  if (son[x]==-1||(num[son[x]]<num[k]))son[x]=k;
              }
         }
    }
    void dfs2(int x,int y)
    {
        top[x]=y;
        if (son[x]!=-1)
         {
             p[x]=pos++;
             fp[p[x]]=x;
             dfs2(son[x],y);
         }
        else
         {
             p[x]=pos++;
             fp[p[x]]=x;
             return;
         } 
        for (int i=fi[x];i;i=ne[i])
         if (zz[i]!=son[x]&&zz[i]!=fa[x])
          dfs2(zz[i],zz[i]); 
    }
    void pushup(int x)
    {
        data[x]=data[x*2]+data[x*2+1];
    }
    void build(int l,int r,int x)
    {
        if (l==r)
         {
             data[x]=val[l];
             return;
         }
        int mid=(l+r)/2; 
        build(l,mid,x*2); 
        build(mid+1,r,x*2+1);
        pushup(x);
    }
    void updata(int p,int q,int l,int r,int x)
    {
        if (l==r)
         {
             data[x]=q;
             return;
         }
        int mid=(l+r)/2;
        if (p<=mid)updata(p,q,l,mid,x*2);
        else updata(p,q,mid+1,r,x*2+1);
        pushup(x); 
    }
    int query(int x,int y,int l,int r,int s)
    {
        if (x>r||y<l)return 0;
        if (x<=l&&y>=r)return data[s];
        int mid=(l+r)/2;
        return query(x,y,l,mid,s*2)+query(x,y,mid+1,r,s*2+1);
    }
    int find(int x,int y)
    {
        int f1=top[x],f2=top[y],temp=0;
        while (f1!=f2)
         {
             if (deep[f1]<deep[f2])
              {
                  swap(x,y);
                  swap(f1,f2);
              }
             temp+=query(p[f1],p[x],1,n,1); 
             x=fa[f1],f1=top[x]; 
         }
        if (x==y)return temp;
        if (deep[x]>deep[y])swap(x,y);
        return temp+query(p[son[x]],p[y],1,n,1); 
    }
    int main()
    {
        pos=1;tot=0;
        memset(fi,0,sizeof fi);
        memset(son,-1,sizeof son);
        memset(data,0,sizeof data);
        scanf("%d%d%d",&n,&m,&ans);
        for (int i=0;i<n-1;i++)
         {
             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
             jb(e[i][0],e[i][1]);jb(e[i][1],e[i][0]);
         }
        dfs1(1,0,0);
        dfs2(1,1);
        for (int i=0;i<n-1;i++)
         {
            if (deep[e[i][0]]<deep[e[i][1]])swap(e[i][0],e[i][1]);
            val[p[e[i][0]]]=e[i][2];
         } 
        build(1,n,1); 
        while (m--)
         {
             scanf("%d",&s);
             if (s==0)scanf("%d",&x),printf("%d
    ",find(x,ans)),ans=x;
             else scanf("%d%d",&x,&y),updata(p[e[x-1][0]],y,1,n,1);
         }
        return 0; 
    }
  • 相关阅读:
    【二分图最大独立集/最小割】P3355 骑士共存问题
    【费用流+正负费用处理】UVA11613 Acme Corporation
    【费用流】P2517 [HAOI2010]订货
    【最小割】P1361 小M的作物
    【最小割】[SHOI2007]善意的投票
    【最小割+割点转换】[USACO5.4]奶牛的电信Telecowmunication
    数据结构学习笔记——ST表
    图论学习笔记——LCA
    基于CNN的手写数字识别程序
    [Atcoder]M-Solutions 题解
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7989017.html
Copyright © 2011-2022 走看看