现在的位置: 首页 > 综合 > 正文

HDU–2586–How far away ?【LCA】

2018年01月12日 ⁄ 综合 ⁄ 共 2326字 ⁄ 字号 评论关闭

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:一棵有边权的树,问任意两点间的长度是多少。

思路:做LCA题目看到的这道题,就用LCA做了,其实只用LCA的递归部分就能做这道题了。

用一个数组dis记录根节点到每个节点的距离,则任意两节点a、b间的距离就是dis[a]+dis[b]-2*dis[lca(a,b)]。

我用vector,交G++要RE,交C++得手动扩栈才能过

LCA离线算法

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 40100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int v,w,next;
}edge[4*MAXN];
int head[MAXN];
int father[MAXN];
int num[MAXN];
int ind[MAXN];//保存每个节点的入度
int vis[MAXN];
int ancestor[MAXN];
vector<int> Qes[MAXN];
map<pair<int,int>,int>mp;
int query[210][2];
int cnt;
int dis[MAXN];

void add_edge(int u,int v,int w){
    edge[cnt].v = v;
    edge[cnt].w = w;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}
void init(int n){
    cnt = 0;
    mp.clear();
    for(int i=1;i<=n;i++){
        dis[i] = 0;
        head[i] = -1;
        num[i] = 1;
        father[i] = i;
        ind[i] = 0;
        ancestor[i] = 0;
        Qes[i].clear();
    }
}
int Find(int x){
    int t = x;
    while(t!=father[t])
        t = father[t];
    int k = x;
    while(k!=t){
        int temp = father[k];
        father[k] = t;
        k = temp;
    }
    return t;
}
int Union(int x,int y){
    int a=Find(x);
    int b=Find(y);
    if(a==b)
        return 0;
    else if(num[a]<=num[b]){
        father[a] = b;
        num[b] += num[a];
    }
    else{
        father[b] = a;
        num[a] += num[b];
    }
    return 1;
}
void LCA(int u,int len){
    int i,j;
    ancestor[u]=u;
    dis[u] = len;
    for(i=head[u];i!=-1;i=edge[i].next){
        int v = edge[i].v;
        LCA(v,len+edge[i].w);
        Union(u,v);
        ancestor[Find(u)] = u;
    }
    vis[u] = 1;
    int _size = Qes[u].size();
    for(i=0;i<_size;i++){
        if(vis[Qes[u][i]]){
            pair<int,int> p;
            if(u>Qes[u][i]) p = make_pair(Qes[u][i],u);
            else    p = make_pair(u,Qes[u][i]);
            mp[p] = ancestor[Find(Qes[u][i])];
        }
    }
}
int main(){
    int t,i,j,n,q;
    int a,b,c;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&q);
        init(n);
        for(i=1;i<n;i++){
            scanf("%d%d%d",&a,&b,&c);
            add_edge(a,b,c);
            ind[b]++;
        }
        for(i=0;i<q;i++){
            scanf("%d%d",&a,&b);
            Qes[a].push_back(b);
            Qes[b].push_back(a);
            query[i][0] = min(a,b);
            query[i][1] = max(a,b);
        }
        for(i=1;i<=n;i++){
            if(ind[i]==0){
                LCA(i,0);
                break;
            }
        }
        for(i=0;i<q;i++){
            pair<int,int> p = make_pair(query[i][0],query[i][1]);
            printf("%d\n",dis[query[i][0]]+dis[query[i][1]]-2*dis[mp[p]]);
        }
        printf("");
    }
    return 0;
}


抱歉!评论已关闭.