HDU 2586 How far away ? (Lca最近公共祖先 在線算法)

貼出來加上註釋方便查看複習,以後會更新總結

題目鏈接 點擊打開鏈接

代碼註釋:

用普通的最短路方法會超時 n到40000

<strong><span style="font-size:18px;color:#ff6600;">#include<iostream>
#include<cstring>
using namespace std;
#define N 40005
struct node
{
    int u,v,w,next;
}a[2*N];  //無向圖結點需2*N
int head[N],dis[N],visit[N],pre[N],rank[N],use[N];//head[]中存的是從同一個點出發的多條邊的編號
int k;
void init()
{
    k=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
    a[k].u=u;
    a[k].v=v;
    a[k].w=w;
    a[k].next=head[u];
    head[u]=k++;  //可以由next訪問到同一個點出發的其他邊的編號
}
void dfs(int u)
{
    use[u]=1;
    for(int i=head[u];i!=-1;i=a[i].next)
    {
        int v=a[i].v;
        if(!use[v])
        {
            dis[v]=dis[u]+a[i].w;
            rank[v]=rank[u]+1;
            pre[v]=u;
            dfs(v);
        }
    }
}
int lca(int u,int v)
{
    if(u==v)
        return u;
    if(rank[u]>rank[v])
        return lca(pre[u],v);
    else
        return lca(u,pre[v]);
}
int main()
{
    int T,n,m,i;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        init();
        int u,v,w;
        for(i=1;i<n;i++)
        {
            cin>>u>>v>>w;
            add(u,v,w);
            add(v,u,w);
        }
        memset(dis,0,sizeof(dis));
        memset(pre,0,sizeof(pre));
        memset(use,0,sizeof(use));
        memset(rank,0,sizeof(rank));
        dfs(1);
        while(m--)
        {
            cin>>u>>v;
            cout<<dis[u]+dis[v]-2*dis[lca(u,v)]<<endl;
        }
    }
}
</span></strong>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章