UVA 11354 Bond Minimum Spanning Tree+lca

Keywords: PHP

meaning of the title

Give a graph, q queries, give uv for each query, find a path so that the maximum edge weight on the path is the smallest of all paths at two points, output this value

thinking

Obviously, the minimum spanning tree must be found first. Any two points have a unique path on the minimum spanning tree, and the maximum edge weight on the path is the output value. The next step is how to find the maximum edge weight on any two unique paths on the tree. First, the minimum spanning tree is converted to a rooted tree, and then u is represented by a fa array.The parent node, the cost array represents the edge of the edge connected to the parent node, and the dep array represents the depth of the point. For each query, first set the depth of the two points to the same size, update the maximum edge, then search up together until the closest common ancestor of the two points, and update the maximum edge.This is the simplest way to find LCA.

 

C++ Code

 

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 7;

struct Edge{
    int from,to;
    int w,nxt;
}edge[maxn << 2],e[maxn << 2];

int n , m ;
int pre[maxn];
int fa[maxn],cost[maxn],dep[maxn];
int head[maxn],tot;

void init(){
    tot = 0;
    memset(head,-1,sizeof head);
    for(int i = 1;i <= n ; i++){
        pre[i] = i;
    }
}

bool cmp(Edge a,Edge b){
    return a.w < b.w;
}

void add_edge(int u ,int v,int w){
    e[tot].from = u;
    e[tot].to = v;
    e[tot].w = w;
    e[tot].nxt = head[u];
    head[u] = tot ++;
}

inline int find(int x){if(x == pre[x])return x;else return pre[x] = find(pre[x]);}

void kruskal(){
    sort(edge+1,edge+1+m,cmp);
    int fu,fv,u,v;
    for(int i = 1;i <= m; i++){
        u = edge[i].from;
        v = edge[i].to;
        fu = find(u);
        fv = find(v);
        if(fu != fv){
            pre[fu] = fv;
            add_edge(u,v,edge[i].w);
            add_edge(v,u,edge[i].w);
        }
    }
}

void dfs(int u,int Fa,int step){
    int v;
    for(int i = head[u]; ~i ;i = e[i].nxt){
        v = e[i].to;
        if(v ==Fa) continue;
        dep[v] = step;
        fa[v] = u;
        cost[v] = e[i].w;
        dfs(v,u,step + 1);
    }
}

int lca(int u,int v){
    int du = dep[u];
    int dv = dep[v];
    int res = 0;
    while(du > dv){
        res = max(res,cost[u]);
        u = fa[u];
        du --;
    }
    while(dv > du){
        res = max(res,cost[v]);
        v = fa[v];
        dv --;
    }
    while(u != v){
        res = max(res,cost[u]);
        res = max(res,cost[v]);
        u = fa[u];
        v = fa[v];
    }
    return res;
}

int main(){
    int cas = 0;
    while(cin >> n >> m){
        if(cas) puts("");
        else cas ++;
        init();
        for(int i = 1;i <= m; i ++){
            int u , v , w;
            cin >> u >> v >> w;
            edge[i].from = u;
            edge[i].to = v;
            edge[i].w = w;
        }
        //cout << 1 ;
        kruskal();
        fa[1] = cost[1] = dep[1] = 0;
        dfs(1,-1,1);
        int q;
        cin >> q;
        while(q--){
            int u , v ;
            cin >> u >> v;
        cout << lca(u,v) << endl;
        }
    }
    return 0;
}

Posted by boogybren on Tue, 30 Jul 2019 14:37:38 -0700