hdu 2586 How far away ?

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

也是一道很裸的LCA,只不过卡了一下栈,要自己开大点栈才能过(c++)。

思路:选1为根节点,先得到从根节点出发到每个点的距离,这样任意两个点的距离为:dis(u)+dis(v)-2*dis(lca(u,v)).

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#pragma comment(linker, "/STACK:36777216")//开大点栈
using namespace std;
const int maxn = 40005;


struct node
{
        int v,w,next;
}edge[maxn*2];
struct nd
{
        int idx,dis;
}as[203];

int vis[maxn],ans[maxn];
int head[maxn],f[maxn];
int dis[maxn],ecnt,cnt;
vector<int>qes[maxn];
vector<int>rank[maxn];


bool cmp(nd a,nd b){ return a.idx < b.idx; }
void add(int u,int v,int w)
{
        edge[ecnt].v = v;
        edge[ecnt].w = w;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}

int Find(int x)
{
        int i = x,tmp;
        while(x!=f[x]) x = f[x];
        while(i!=f[x]){ tmp = f[i]; f[i] = x; i = tmp;}
        return f[x];
}

void LCA(int pre,int u,int sum)
{
        int i,v,x,y;
        ans[u] = u;
        dis[u] = sum;
        for(i = head[u]; i != -1; i = edge[i].next){
                v = edge[i].v;
                if(v==pre)continue;
                LCA(u,v,sum+edge[i].w);
                x = Find(u);
                y = Find(v);
                if(x!=y) f[y] = x;
                ans[Find(u)] = u;
        }
        vis[u] = 1;
        for(i = 0; i < qes[u].size(); ++ i){
                v = qes[u][i];
                if(vis[v]){
                        as[cnt].idx = rank[u][i];
                        as[cnt].dis = dis[v] + dis[u] - dis[ans[Find(v)]] * 2;
                        cnt++;
                }
        }
}
int main()
{
        int i,j,k,u,v,w,n,m,t;
        scanf("%d",&t);
        while(t--)
        {
                scanf("%d %d",&n,&m);
                memset(vis,0,sizeof(vis));
                memset(ans,0,sizeof(ans));
                memset(head,-1,sizeof(head));
                for(i = 0; i <= n; ++ i) qes[i].clear();
                for(i = 0; i <= n; ++ i) f[i] = i;
                ecnt = cnt = 0;
                for(i = 1; i < n; ++ i)
                {
                        scanf("%d %d %d",&u,&v,&w);
                        add(u,v,w);
                        add(v,u,w);
                }
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d",&u,&v);
                        qes[u].push_back(v);
                        qes[v].push_back(u);
                        rank[u].push_back(i);
                        rank[v].push_back(i);
                }
                LCA(0,1,0);
                sort(as,as+cnt,cmp);
                for(i = 0; i < m; ++ i) printf("%d\n",as[i].dis);
        }return 0;
}

 

 

posted on 2012-06-19 11:58  aigoruan  阅读(205)  评论(0)    收藏  举报

导航