Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

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

LCA  Tarjan算法

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int N=10010,M=20010;
struct edge
{
    int v,w,next;
}e[M];
int em;
int head[N],n;
struct qes
{
    int v,k;
};
vector<qes> q[N];
int dis[N],vis[N],set[N],anc[N],col[N],cc;
int ans[1000010];
void insert(int u,int v,int w)
{
    edge et={v,w,head[u]};
    e[em]=et;
    head[u]=em++;
}
void graphinit()
{
    em=0;
    memset(head,-1,sizeof(head));
}
void qesinit()
{
    cc=0;
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(col,0,sizeof(col));
    for(int i=1;i<=n;i++) q[i].clear();
}
int find(int x)
{
    return x==set[x]?x:set[x]=find(set[x]);
}
void merge(int u,int v)
{
    set[find(v)]=find(u);
}
void LCA(int u,int d)
{
    set[u]=u;
    vis[u]=1;
    dis[u]=d;
    anc[find(u)]=u;
    for(int i=head[u];i!=-1;i=e[i].next) if(!vis[e[i].v])
    {
        int v=e[i].v;
        LCA(v,d+e[i].w);
        merge(u,v);
        anc[find(u)]=u;
    }
    col[u]=cc;
    int sz=q[u].size();
    for(int i=0;i<sz;i++)
    {
        int v=q[u][i].v, k=q[u][i].k;
        if(col[v]==cc) ans[k]=dis[u]+dis[v]-2*dis[anc[find(v)]];
        else ans[k]=-1;
    }
}
int main()
{
    int m,c;
    while(~scanf("%d%d%d",&n,&m,&c))
    {
        graphinit();
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            insert(u,v,w);
            insert(v,u,w);
        }
        qesinit();
        for(int i=0;i<c;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            qes t1={v,i};
            q[u].push_back(t1);
            qes t2={u,i};
            q[v].push_back(t2);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i]) {cc++; LCA(i,0);}
        for(int i=0;i<c;i++)
            if(ans[i]!=-1) printf("%d\n",ans[i]);
            else printf("Not connected\n");
    }
    return 0;
}

posted on 2012-05-08 09:50  Qiuqiqiu  阅读(318)  评论(0编辑  收藏  举报