码迷,mamicode.com
首页 > 其他好文 > 详细

poj2763

时间:2015-05-29 23:02:04      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

//Accepted    11676 KB    2344 ms
/*
    source:poj2763
    time  :2015.5.29
    by    :songt
  */
/*题解:
树链剖分
基于边权,路径查询
wind第一次在s节点,假如她走到了p节点,那么下次开始的时候他就在p节点
  */
#include <cstdio>
#include <cstring>

const int imax_n = 100005;
struct Edge
{
    int u,v;
    Edge(){}
    Edge(int u,int v):u(u),v(v){}
}edge[2*imax_n];
int head[imax_n];
int next[2*imax_n];
int tot;
void addEdge(int u,int v)
{
    edge[tot]=Edge(u,v);
    next[tot]=head[u];
    head[u]=tot++;
}
int fa[imax_n],deep[imax_n],num[imax_n],son[imax_n];
int p[imax_n],fp[imax_n],top[imax_n];
int pos;
void init()
{
    memset(head,-1,sizeof(head));
    memset(next,-1,sizeof(next));
    tot=0;
    memset(son,-1,sizeof(son));
    pos=0;
}
int s[imax_n];
int cnt_s;
int vis[imax_n];
void dfs1(int u)
{
    fa[u]=0;
    deep[u]=0;
    cnt_s=0;
    s[cnt_s++]=u;
    memset(vis,0,sizeof(vis));
    while (cnt_s)
    {
        int x=s[cnt_s-1];
        if (vis[x])
        {
            cnt_s--;
            if (x!=u)
            {
                num[fa[x]]+=num[x];
                if (son[fa[x]]==-1 || num[fa[x]]<num[x])
                    son[fa[x]]=x;
            }
            continue;
        }
        vis[x]=1;
        num[x]=1;
        for (int i=head[x];i+1;i=next[i])
        {
            int v=edge[i].v;
            if (v!=fa[x])
            {
                fa[v]=x;
                deep[v]=deep[x]+1;
                s[cnt_s++]=v;
            }
        }
    }
}
void dfs2(int u)
{
    top[u]=u;
    memset(vis,0,sizeof(vis));
    cnt_s=0;
    s[cnt_s++]=u;
    while (cnt_s)
    {
        int x=s[cnt_s-1];
        if (vis[x])
        {
            cnt_s--;
            continue ;
        }
        vis[x]=1;
        p[x]=pos++;
        fp[p[x]]=x;
        if (son[x]==-1) continue ;
        for (int i=head[x];i+1;i=next[i])
        {
            int v=edge[i].v;
            if (v!=fa[x] && v!=son[x])
            {
                top[v]=v;
                s[cnt_s++]=v;
            }
        }
        top[son[x]]=top[x];
        s[cnt_s++]=son[x];
    }
}
struct Tree
{
    int l,r;
    long long sum;
}f[imax_n*3];
void build(int t,int l,int r)
{
    f[t].l=l;
    f[t].r=r;
    f[t].sum=0;
    if (l==r)
    {
        return ;
    }
    int mid=(f[t].l+f[t].r)>>1;
    build(2*t,l,mid);
    build(2*t+1,mid+1,r);
}
void update(int t,int k,int value)
{
    if (f[t].l==k && f[t].r==k)
    {
        f[t].sum=value;
        return ;
    }
    int mid=(f[t].l+f[t].r)>>1;
    if (k<=mid) update(2*t,k,value);
    else update(2*t+1,k,value);
    f[t].sum=f[2*t].sum+f[2*t+1].sum;
}
long long query(int t,int l,int r)
{
    if (f[t].l==l && f[t].r==r)
    {
        return f[t].sum;
    }
    int mid=(f[t].l+f[t].r)>>1;
    if (r<=mid) return query(2*t,l,r);
    else
    {
        if (l>mid) return query(2*t+1,l,r);
        else return query(2*t,l,mid)+query(2*t+1,mid+1,r);
    }
}
void swap(int &a,int &b)
{
    int t=a;
    a=b;
    b=t;
}
long long find(int u,int v)
{
    int f1=top[u],f2=top[v];
    long long sum=0;
    while (f1!=f2)
    {
        if (deep[f1]<deep[f2])
        {
            swap(f1,f2);
            swap(u,v);
        }
        sum+=query(1,p[f1],p[u]);
        u=fa[f1];
        f1=top[u];
    }
    if (u==v) return sum;
    if (deep[u]>deep[v]) swap(u,v);
    sum+=query(1,p[son[u]],p[v]);
    return sum;
}
int e[imax_n][3];
int n,m;
int res;

int main()
{
    while (scanf("%d%d%d",&n,&m,&res)==3)
    //scanf("%d%d%d",&n,&m,&res);
    {
        init();
        for (int i=0;i<n-1;i++)
        {
            scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
            addEdge(e[i][0],e[i][1]);
            addEdge(e[i][1],e[i][0]);
        }
        dfs1(1);
        dfs2(1);
        build(1,0,pos-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]);
            update(1,p[e[i][0]],e[i][2]);
        }
        int kind;
        int u,v;
        for (int i=0;i<m;i++)
        {
            scanf("%d",&kind);
            if (kind==0)
            {
                scanf("%d",&u);
                printf("%lld\n",find(u,res));
                res=u;
            }
            else
            {
                scanf("%d%d",&u,&v);
                update(1,p[e[u-1][0]],v);
            }
        }
    }
    return 0;
}

 

poj2763

标签:

原文地址:http://www.cnblogs.com/djingjing/p/4539470.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!