POJ 2586 How far away ? 离线LCA

来源:互联网 发布:sql 字段累加 编辑:程序博客网 时间:2024/06/06 01:48

题目链接

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

题意

给定一颗含有n个结点的树,以及q个询问。对于每个询问,输出两顶点间的最短距离。

思路

LCA离线,将每个询问先存储,每个询问的答案在搜索树时计算,代码思路很清楚。

#include<cstdio>#include<queue>#include<iostream>#include<vector>#include<map>#include<cstring>#include<string>#include<set>#include<stack>#include<algorithm>#define cle(a) memset(a,0,sizeof(a))#define inf(a) memset(a,0x3f,sizeof(a))#define ll long long#define Rep(i,a,n) for(int i=a;i<=n;i++)using namespace std;#define INF2 9223372036854775807llconst int INF = ( 2e9 ) + 2;const ll maxn = 4e4+10;int head[maxn],vis[maxn],head2[maxn],d[maxn],f[maxn],ans[maxn];int Find(int x){    return f[x]==x?x:f[x]=Find(f[x]);}struct Q{    int v,id,next;} que[300*2];struct edge{    int v,w,next;} e[maxn*2];int tot,tot2;void addedge(int u,int v,int w){    e[tot].v=v;    e[tot].w=w;    e[tot].next=head[u];    head[u]=tot++;    e[tot].v=u;    e[tot].w=w;    e[tot].next=head[v];    head[v]=tot++;}void dfs(int u){    vis[u]=1;    f[u]=u;    for(int i=head2[u]; i!=-1; i=que[i].next)    {        int v=que[i].v;        int id=que[i].id;        if(vis[v])ans[id]=d[u]+d[v]-d[Find(v)]*2;    }    for(int i=head[u]; i!=-1; i=e[i].next)    {        int v=e[i].v;        if(!vis[v])        {            d[v]=d[u]+e[i].w;            dfs(v);            f[v]=u;        }    }}void init(int n){    tot=tot2=0;    memset(head,-1,sizeof(head));    memset(head2,-1,sizeof(head2));    memset(vis,0,sizeof(vis));    memset(d,0,sizeof(d));    for(int i=1; i<=n; i++)f[i]=i;}int main(){    int t;//  freopen("in.txt","r",stdin);//  freopen("out1.txt","w",stdout);     scanf("%d",&t);    while(t--)    {        int n,q;        int u,v,w;        scanf("%d%d",&n,&q);        init(n);        for(int i=0; i<n-1; i++)        {            scanf("%d%d%d",&u,&v,&w);            addedge(u,v,w);        }        for(int i=0; i<q; i++)        {            scanf("%d%d",&u,&v);            que[tot2].v=v;            que[tot2].id=i;            que[tot2].next=head2[u];            head2[u]=tot2++;            que[tot2].v=u;            que[tot2].id=i;            que[tot2].next=head2[v];            head2[v]=tot2++;        }        dfs(1);        for(int i=0; i<q; i++)            printf("%d\n",ans[i]);    }}
原创粉丝点击