HDU2874

题意:一个森林,求2点之间的距离


分析:tarjan离线求LCA,在tarjan过程中顺便求2点是否联通


#include 
#include
#include
#include
#include
#include
#define N 10005
#define M 1000005
using namespace std;
int cnt_e,cnt_q,head_e[N],head_q[N],vis[N],dis[N],t,ans[M],id[N],f[N];
struct node{
    int u,w,next;
}e[N*2],q[M*2];
void init(){
    memset(head_e,-1,sizeof(head_e));
    memset(head_q,-1,sizeof(head_q));
    memset(vis,0,sizeof(vis));
    cnt_e=0;
    cnt_q=0;

}
void addedge(int x,int y,int z){
    e[cnt_e].u=x;e[cnt_e].w=z;e[cnt_e].next=head_e[y];head_e[y]=cnt_e++;
    e[cnt_e].u=y;e[cnt_e].w=z;e[cnt_e].next=head_e[x];head_e[x]=cnt_e++;
}
void addquery(int x,int y,int z){
    q[cnt_q].u=x;q[cnt_q].w=z;q[cnt_q].next=head_q[y];head_q[y]=cnt_q++;
    q[cnt_q].u=y;q[cnt_q].w=z;q[cnt_q].next=head_q[x];head_q[x]=cnt_q++;
}
int find(int x){
    if(f[x]==x)
    return x;
    return f[x]=find(f[x]);
}
void tarjan(int k){
    f[k]=k;
    vis[k]=1;
    id[k]=t;
    int i,v;
    for(i=head_q[k];i!=-1;i=q[i].next){
        v=q[i].u;
        if(vis[v]){
            if(id[v]==id[k])
            ans[q[i].w]=dis[k]+dis[v]-2*dis[find(v)];
            else
            ans[q[i].w]=-1;
        }
    }
    for(i=head_e[k];i!=-1;i=e[i].next){
        v=e[i].u;
        if(!vis[v]){
            dis[v]=dis[k]+e[i].w;
            tarjan(v);
            f[v]=k;
        }
    }
}
int main(){
    int i,n,m,c,x,y,z;
        while(~scanf("%d%d%d",&n,&m,&c)){
        init();
        while(m--){
            scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
        }
        for(i=0;i


分析:LCA,在tarjan中判断2个点是否联通

你可能感兴趣的:(LCA)