zoukankan      html  css  js  c++  java
  • noip不知道哪年 货车运输

    题意:最大生成树上找

    q组两个点的lca

    然后求出u->lca->v这条路径上的最小边

    倍增大法好

    # include <iostream>
    # include <stdio.h>
    # include <stdlib.h>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define ll long long
    # define Fill(a, b) memset(a, b, sizeof(a));
    using namespace std;
    
    IL ll Read(){
        char c = '%'; ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
        return x * z;
    }
    
    const int MAXN = 20001, MAXM = 200001;
    int ft[MAXN], n, m, cnt, fa[MAXN][20], w[MAXN], deep[MAXN], Fa[MAXN], num;
    struct Edge{
        int to, nt;
    } edge[MAXM];
    struct Kruskal{
        int u, v, f;
        IL bool operator <(Kruskal b) const{
            return f > b.f;
        }
    } road[MAXM];
    
    IL int Find(int x){
        return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);
    }
    
    IL void Add(int u, int v){
        edge[cnt] = (Edge){v, ft[u]}; ft[u] = cnt++;
        edge[cnt] = (Edge){u, ft[v]}; ft[v] = cnt++;
    }
    
    IL void Dfs(int u){
        for(int e = ft[u]; e != -1; e = edge[e].nt){
            int v = edge[e].to;
            if(!deep[v]){
                deep[v] = deep[u] + 1;
                fa[v][0] = u;
                Dfs(v);
            }
        }
    }
    
    IL int LCA(int u, int v){
        if(Find(u) != Find(v)) return -1;
        if(deep[u] < deep[v]) swap(u, v);
        for(int i = 18; i >= 0; i--)
            if(deep[fa[u][i]] >= deep[v]) u = fa[u][i];
        if(u == v) return w[u];
        for(int i = 18; i >= 0; i--)
            if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
        return w[fa[u][0]];
    }
    
    int main(){
        Fill(ft, -1);
        num = n = Read(); m = Read();
        for(int i = 1; i <= 2 * n; i++)
            Fa[i] = i;
        for(int i = 1; i <= m; i++)
            road[i] = (Kruskal){Read(), Read(), Read()};
        sort(road + 1, road + m + 1);
        for(int i = 1, tot = 0; i <= m && tot < n; i++){
            int u = Find(road[i].u), v = Find(road[i].v);
            if(u != v){
                tot++;
                w[++num] = road[i].f;
                Fa[u] = Fa[v] = num;
                Add(u, num); Add(v, num);
            }
        }
        for(int i = num; i; i--)
            if(!deep[i]) deep[i] = 1, Dfs(i);
        for(int i = 1; i <= 18; i++)
            for(int j = 1; j <= num; j++)
                fa[j][i] = fa[fa[j][i - 1]][i - 1];
        int Q = Read();
        while(Q--){
            int u = Read(), v = Read();
            printf("%d
    ", LCA(u, v));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python修改文件内容
    Python实现用户注册到文件
    Postman接口测试
    Linux下安装LoadRunner LoadGenerator
    Loadrunner参数化避免重复数据
    Ta-Lib用法介绍 !
    迭代器 生成器
    深入理解python多进程编程
    python多进程
    python多线程
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/7620028.html
Copyright © 2011-2022 走看看