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

来源:互联网 发布:c语言实现模拟退火算法 编辑:程序博客网 时间:2024/04/28 20:31

贴出来加上注释方便查看复习,以后会更新总结

题目链接 点击打开链接

代码注释:

用普通的最短路方法会超时 n到40000

<strong><span style="font-size:18px;color:#ff6600;">#include<iostream>#include<cstring>using namespace std;#define N 40005struct node{    int u,v,w,next;}a[2*N];  //无向图结点需2*Nint 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>


0 0