HDU 2586——How far away ?(LCA)

来源:互联网 发布:程序员游戏 编辑:程序博客网 时间:2024/06/09 01:39

题目大意:给出一个图,保证两点之间有且仅有一条边连接,求亮点之间的距离。

思路:将图转化为树,然后求最近公共祖先(LCA)。Tarjan算法,图用前向星存储。

开始几次把数组开小了,然后错了好多次。也发现了一个问题,当数组开小了的时候,在杭电上面用G++提交时WA,用C++提交时RE。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<stack>using namespace std;const int maxn=40005;int first[maxn];int tot;int ancestor[maxn];int check[maxn];int weight[maxn];int n,m;struct Edge{    int u,v,next;    int w;}edge[maxn*2];struct question{    int u,v,ans;}queries[maxn];void addedge(int u,int v,int w){    edge[tot].u=u;    edge[tot].v=v;    edge[tot].w=w;    edge[tot].next=first[u];    first[u]=tot++;}int findset(int u){    if(u!=ancestor[u])ancestor[u]=findset(ancestor[u]);    return ancestor[u];}void unionset(int a,int b){    b=findset(b);    a=findset(a);    ancestor[b]=ancestor[a];}void lca(int u){    ancestor[u]=u;    check[u]=true;    for(int i=0;i<m;++i){        int &x=queries[i].u;        int &y=queries[i].v;        int &z=queries[i].ans;        if(x==u&&check[y])z=findset(y);        if(y==u&&check[x])z=findset(x);    }    for(int i=first[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(check[v])continue;        weight[v]=weight[u]+edge[i].w;        lca(v);        ancestor[v]=u;    }}int main(){ //  freopen("data.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        tot=0;        memset(first,-1,sizeof(first));        memset(check,0,sizeof(check));        for(int i=0;i<maxn;++i){            edge[i].next=-1;        }        for(int i=0;i<=n;++i){            ancestor[i]=i;        }        weight[1]=0;        //³õʼ»¯        scanf("%d%d",&n,&m);        for(int i=0;i<n-1;++i){            int ii,jj,kk;            scanf("%d%d%d",&ii,&jj,&kk);            addedge(ii,jj,kk);            addedge(jj,ii,kk);        }        for(int i=0;i<m;++i){            int u,v;            scanf("%d%d",&u,&v);            queries[i].u=u;            queries[i].v=v;        }        lca(1);        int rec=0;        for(int i=0;i<m;++i){                rec++;                int &u=queries[i].u;                int &v=queries[i].v;                int &p=queries[i].ans;                printf("%d\n",weight[u]+weight[v]-2*weight[p]);        }        while(rec!=m); //       printf("\n");    }    return 0;}


0 0
原创粉丝点击