absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] [-4] BZOJ 1013
[破碎的状态] [-2] 模拟退火

[破碎的状态] [-4] Hdu 2586

absi2011 posted @ Jul 18, 2016 10:04:04 PM in 刷题记录 with tags LCA 小高考 HDU , 666 阅读

感谢@JCarlson 提供题目和题意

题意:

给你一个带权图,求路径上权值和

做法:

LCA..

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int up[40005][25];
int sum[40005][25];
int father[40005];
int up_val[40005];
struct edge
{
    int y;
    int weight;
    edge * next;
};
edge * li[100005];
edge * new_edge()
{
    static edge a[1000005];
    static int top=0;
    return &a[top++];
}
void inserts(int x,int y,int z)
{
    edge * t=new_edge();
    t->y=y;
    t->weight=z;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y,int z)
{
    inserts(x,y,z);
    inserts(y,x,z);
}
int depth[40005];
void dfs(int x)
{
    up[x][0]=father[x];
    sum[x][0]=up_val[x];
    int i;
    for (i=1;i<20;i++)
    {
        if (up[x][i-1]==-1)
        {
            up[x][i]=-1;
            sum[x][i]=sum[x][i-1];
        }
        else
        {
            up[x][i]=up[up[x][i-1]][i-1];
            sum[x][i]=sum[x][i-1]+sum[up[x][i-1]][i-1];
        }
    }
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==father[x]) continue;
        father[t->y]=x;
        up_val[t->y]=t->weight;
        depth[t->y]=depth[x]+1;
        dfs(t->y);
    }
}
int lca(int x,int y)
{
    if (depth[x]<depth[y]) swap(x,y);
    int t=depth[x]-depth[y];
    int i;
    int ans=0;
    for (i=0;i<20;i++)
    {
        if ((1<<i)&t)
        {
            ans+=sum[x][i];
            x=up[x][i];
        }
    }
    if (x==y) return ans;
    for (i=19;i>=0;i--)
    {
        if (up[x][i]!=up[y][i])
        {
            ans+=sum[x][i];
            ans+=sum[y][i];
            x=up[x][i];
            y=up[y][i];
        }
    }
    return ans+sum[x][0]+sum[y][0];
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int t;
    scanf("%d",&t);
    int zu;
    for (zu=0;zu<t;zu++)
    {
        memset(li,0,sizeof(li));
        int n,m;
        scanf("%d%d",&n,&m);
        int i;
        for (i=1;i<n;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            x--;
            y--;
            insert_edge(x,y,z);
        }
        father[0]=-1;
        up_val[0]=0;
        depth[0]=0;
        dfs(0);
        for (i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x--;
            y--;
            printf("%d\n",lca(x,y));
        }
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter