• tarjian(求最短距离)


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

    题意:给出一颗n个节点,n-1边且有距离(带权),m次询问,问两点间最短距离。

    解法:记录每一个节点到根节点(默认为1)距离,u、v两点距离为dis[u]+dis[v]-2*dis[fa].

    //#include<bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SC scanf
    #define rep(i , j , n) for(int i = j ; i <= n ; i++)
    #define red(i , n , j)  for(int i = n ; i >= j ; i--)
    #define INF  0x3f3f3f3f
    #define mod 1000000007
    #define PI acos(-1)
    #define pii pair<int,int>
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll ;
    const int maxn = 4e4+9;
    int head[maxn] , qhead[maxn] , tol , qtol , vis[maxn] , f[maxn] , ans[maxn] , dis[maxn];
    int n , m ;
    struct node{
        int to , next , w;
    }g[maxn<<1];
    
    struct query{
        int to , next , id;
    }q[maxn];
    
    void init(){//初始化
        ME(head , 0);
        ME(qhead , 0);
        ME(vis , 0);
        ME(dis , 0);
        tol = 0 , qtol = 0;
        rep(i , 1 , n){
            f[i] = i ;
        }
     }
    
    void add(int u , int v , int w){//建边
        g[++tol] = {v , head[u] , w};
        head[u] = tol ;
    }
    
    void qadd(int u , int v , int id){//需查询的两点
        q[++qtol] = {v , qhead[u] , id};
        qhead[u] = qtol;
    }
    
    int find(int x){
        return x == f[x] ? x :find(f[x]);
    }
    void unite(int u , int v){
        f[v] = u ;
    }
    
    void dfs(int u , int d){
        vis[u] = 1 ;
        for(int i = head[u] ; i ; i = g[i].next){
            int v = g[i].to;
            dis[u] = d ;
            if(vis[v]) continue;
            dfs(v , d+g[i].w);
            unite(u , v);
        }
        for(int i = qhead[u] ; i ; i = q[i].next){
            int v = q[i].to;
            if(vis[v]){
                int fa = find(v);
                ans[q[i].id] = dis[u] + dis[v] - 2*dis[fa];
            }
        }
    }
    
    void solve(){
        cin >> n >> m ;
        init();
        rep(i , 1 , n-1){
            int u , v , w ;
            scanf("%d%d%d" , &u , &v , &w);
            add(u , v , w);
            add(v , u , w);
        }
        rep(i , 1 , m){
            int u , v ;
            scanf("%d%d" , &u , &v);
            qadd(u , v , i);
            qadd(v , u , i);
        }
        dfs(1 , 0);
        rep(i , 1 , m){
            cout << ans[i] << endl;
        }
    }
    
    int main()
    {
        int t;cin >> t ;
        while(t--){
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    WiFi 和蓝牙一体的 ESP32 芯片及乐鑫官方的 Arduino 开发工具包
    给模块添加 USB 支持的 USB Host Shield Mini
    设备间数据通信 —— 串行外设接口(SPI)协议
    ESP32 开发板刷入 MicroPython
    芯片、模组、开发板以及业余爱好者如何选择
    快速了解线路板(PCB)基础知识
    终端发展过程及 tty、pty、pts 的区别
    时间类型和时间戳
    使用Qt实现一个必应壁纸客户端
    给网站添加Let's Encrypt的免费ssl证书
  • 原文地址:https://www.cnblogs.com/nonames/p/12323881.html
Copyright © 2020-2023  润新知