码迷,mamicode.com
首页 > 其他好文 > 详细

HD2586 LCA水题

时间:2017-10-07 14:31:50      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:oid   tar   --   gre   main   16px   空调   net   end   

 

强连通
 1269  迷宫城堡
 2767 Proving Equivalences
 3836 Equivalent Sets
 1827 Summer Holiday
 3072 Intelligence System
 3861 The King’s Problem
 3639 Hawk-and-Chicken
 3594 Cactus 仙人掌图
 4685
[双连通]:
2242 考研路茫茫——空调教室  双联通缩点+树形DP
2460 Network 边双连通
3849 By Recognizing These Guys, We Find Social Networks Useful  双连通求桥
3896 Greatest TC  双连通
4005 The war  边双连通
3394 Railway 双连通求块

[LCA]:
2586 How far away ?
2874 Connections between cities
3078 Network  
3830 Checkers 
4338 Simple Path 

 

 

 

参考Vendetta

     需要补充的是vis可以在访问到节点时就标记,也可以在访问完其子孙后再标记,区别在于前者可以查询a和b的关系以及b和a的关系,而后者只能查询b和a的关系(假设先访问a),但既然是无向图,答案是一样的,目测放前面可能更强大。

 

#include<cstdio>
#include<cstring>
#include<cstring>
#include<iostream>
int const MAX = 40005;
struct Edge
{
    int id, val;
    int next;  
}e[2 * MAX];
int n, m, cnt;
int x[MAX], y[MAX], z[MAX];
int fa[MAX], dist[MAX], pre[MAX];
bool vis[MAX];
void _add(int u, int v, int w)
{
    e[cnt].id = u; 
    e[cnt].val = w; 
    e[cnt].next = pre[v]; 
    pre[v] = cnt++;
}
int Find(int x)
{
    return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void tarjan(int k)
{ 
    vis[k]=true;
    fa[k]=k;
    for(int i=pre[k];i;i=e[i].next){
        if(!vis[e[i].id]){
            dist[e[i].id]=dist[k]+e[i].val;
            tarjan(e[i].id);
            fa[e[i].id] = k;
        }
    }    
    //vis[k]=true;
    for(int i=1;i<=m;i++){
        if(x[i]==k&&vis[y[i]]) 
            z[i]=Find(y[i]);
    }
}
int main()
{
    int T,u,v,w;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d", &n, &m);
        cnt=0;
        memset(pre,0,sizeof(pre));
        for(int i=1;i<n;i++){
            scanf("%d %d %d",&u,&v,&w);
            _add(u,v,w);
            _add(v,u,w);
        }
        for(int i=1;i<=n;i++)
            x[i]=y[i]=z[i]=0;
        for(int i=1;i<=m;i++)
            scanf("%d %d",&x[i],&y[i]);
        memset(vis, false, sizeof(vis));
        dist[1] = 0;
        tarjan(1);
        for(int i = 1; i <= m; i++)
            printf("%d\n",dist[x[i]] + dist[y[i]] - 2 * dist[z[i]]);
    }
}

 

HD2586 LCA水题

标签:oid   tar   --   gre   main   16px   空调   net   end   

原文地址:http://www.cnblogs.com/hua-dong/p/7634270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!