hdu 2874 Connections between cities

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

裸LCA,处理森林的无向图。

思路:给每棵树一个唯一的编号,查LCA的时候,判断一下是不是在同一棵树下就行了。

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:36777216")
using namespace std;
const int maxn = 10005;
struct node{
        int to,next,w;
}edge[maxn*2];

struct nd
{
        int to,idx,next;
}qes[maxn*200];
int ans[maxn*100];
int h[maxn],hh[maxn];
int vis[maxn],fa[maxn];
int dis[maxn];
int ecnt1,ecnt2;
void add(int s,int t,int w)
{
        edge[ecnt1].to = t;
        edge[ecnt1].w = w;
        edge[ecnt1].next = h[s];
        h[s] = ecnt1++;
}
void ADD(int s,int t,int idx)
{
        qes[ecnt2].to = t;
        qes[ecnt2].idx = idx;
        qes[ecnt2].next = hh[s];
        hh[s] = ecnt2++;
}
int fun(int x)
{
        if(x!=fa[x]) fa[x] = fun(fa[x]);
        return fa[x];
}
void tarjan(int pre,int u,int root,int sum)
{
        int i,v,x,y;
        dis[u] = sum;
        vis[u] = root;
        for(i = h[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].to;
                if(vis[v])continue;
                tarjan(u,v,root,sum+edge[i].w);
                x = fun(u);
                y = fun(v);
                if(x!=y) fa[y] = x;
        }
        for(i = hh[u]; i != -1; i = qes[i].next)
        {
                v = qes[i].to;
                x = qes[i].idx;
                if(vis[v]==root&&ans[x]<0)
                        ans[x] = dis[u] + dis[v] - dis[fun(v)] * 2;
        }
}
int main()
{
        int i,j,k,s,t,n,m,c,w;
        while(scanf("%d %d %d",&n,&m,&c)==3)
        {
                memset(h,-1,sizeof(h));
                memset(hh,-1,sizeof(hh));
                memset(vis,0,sizeof(vis));
                memset(ans,-1,sizeof(ans));
                for(i = 0; i <= n; ++ i) fa[i] = i;

                ecnt1 = ecnt2 = 0;
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d %d",&s,&t,&w);
                        add(s,t,w);
                        add(t,s,w);
                }
                for(i = 0; i < c; ++ i)
                {
                        scanf("%d %d",&s,&t);
                        ADD(s,t,i);
                        ADD(t,s,i);
                }
                for(i = 1; i <= n; ++ i)if(!vis[i])
                        tarjan(0,i,i,0);
                for(i = 0; i < c; ++ i)
                if(ans[i]==-1) puts("Not connected");
                else printf("%d\n",ans[i]);

        }return 0;
}

 

posted on 2012-06-19 15:35  aigoruan  阅读(182)  评论(0)    收藏  举报

导航