zoukankan      html  css  js  c++  java
  • UVA

    题意:多组询问,每组询问求无向图中两个结点间最小瓶颈路的最大边权

    算是带权并查集的一道板子题吧,首先用kruskal算法构建最小生成树,构建过程中并查集按秩合并,同时每个点记录一个cost值,表示把该点与父亲结点合并所需的最小代价,那么两点间最小瓶颈路的最大边权就是带权并查集上两点之间路径的最大边权,用类似求LCA的方法自底向上跳就可以求出

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10,inf=0x3f3f3f3f;
     5 int n,m,fa[N],siz[N],cost[N],Q,ka;
     6 struct E {
     7     int u,v,c;
     8     bool operator<(const E& b)const {return c<b.c;}
     9 } e[N];
    10 int fd(int x) {return fa[x]?fd(fa[x]):x;}
    11 void mg(int x,int y,int c) {
    12     if((x=fd(x))==(y=fd(y)))return;
    13     if(siz[x]>siz[y])swap(x,y);
    14     fa[x]=y,siz[y]+=siz[x],cost[x]=c;
    15 }
    16 void kruskal() {
    17     for(int i=1; i<=n; ++i)fa[i]=0,siz[i]=1;
    18     sort(e+1,e+1+m);
    19     for(int i=1; i<=m; ++i) {
    20         int u=e[i].u,v=e[i].v,c=e[i].c;
    21         mg(u,v,c);
    22     }
    23 }
    24 int qry(int u,int v) {
    25     int ret=0;
    26     while(u!=v) {
    27         if(siz[u]>siz[v])swap(u,v);
    28         ret=max(ret,cost[u]);
    29         u=fa[u];
    30     }
    31     return ret;
    32 }
    33 
    34 int main() {
    35     while(~scanf("%d%d",&n,&m)) {
    36         if(ka++)puts("");
    37         for(int i=1; i<=m; ++i)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
    38         kruskal();
    39         scanf("%d",&Q);
    40         while(Q--) {
    41             int u,v;
    42             scanf("%d%d",&u,&v);
    43             printf("%d
    ",qry(u,v));
    44         }
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    GotoAndPlay 图论
    P1965 转圈游戏  快速幂
    双栈排序 图论
    威尔逊定理 数学
    n!mod p 的求法 数学
    P3195 [HNOI2008]玩具装箱TOY DP+优化
    loj6485. LJJ 学二项式定理
    loj6539. 奇妙数论题
    loj535. 「LibreOJ Round #6」花火
    loj534. 「LibreOJ Round #6」花团
  • 原文地址:https://www.cnblogs.com/asdfsag/p/14618035.html
Copyright © 2011-2022 走看看