zoukankan      html  css  js  c++  java
  • UVA11354 Bond 并查集

      题意:给出一张n个点m条边的无向图, 每条边有一个危险度,有q个询问, 每次给出两个点s、t,找一条路, 使得路径上的最大危险度最小

    按秩合并并查集

    不能路径压缩  否则就破坏了其树形结构

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=1e6+10;
    
    int f[N],x,y,q,n,m,siz[N],w[N];
    struct Edge
    {
        int u,v,w;
    }edge[N];
    int find1(int x)
    {
        return f[x]==x?x:find1(f[x]);
    }
    
    void kruscal()
    {
        sort(edge+1,edge+1+m,[](Edge a,Edge b){return a.w<b.w;});
        int cnt=0;
        rep(i,1,n)f[i]=i,siz[i]=1;
        CLR(w,0);
        rep(i,1,m)
        {
            int x=find1(edge[i].u),y=find1(edge[i].v);
            if(x==y)continue;
            if(siz[x]<siz[y])
            {
                f[x]=y;
                siz[y]=max(siz[y],siz[x]+1);
                w[x]=edge[i].w;
            }
            else
            {
                f[y]=x;
                siz[x]=max(siz[x],siz[y]+1);
                w[y]=edge[i].w;
            }
            cnt++;
            if(cnt==n-1)break;
        }
    }
    int c[N];
    int query(int x,int y)
    {
        rep(i,1,n)c[i]=-1;
        int ans=0,temp=0;
        while(1)
        {
            c[x]=temp;
            if(f[x]==x)break;
            temp=max(temp,w[x]);
            x=f[x];
        }
        while(1)
        {
            if(c[y]>=0){ans=max(ans,c[y]);break;}//lca相同时就退出
            if(f[y]==y)break;
            ans=max(ans,w[y]);
            y=f[y];
        }
        return ans;
    }
    
    int main()
    {   
        int ok=0;
        while(scanf("%d%d",&n,&m)==2)
        {   
            if(ok)printf("
    ");
            ok=1;
            rep(i,1,m)
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
            kruscal();
            scanf("%d",&q);
            while(q--)
            {
                scanf("%d%d",&x,&y);
                printf("%d
    ",query(x,y));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    crash reporting system for Windows applications
    1
    qt 试用 (3)配置编译源代码及调试
    kd tree & ray tracing
    new
    KMP算法中关于next数组的探究
    teamviewer vs echovnc
    NAT之stun确定nat类型
    Wireshark
    GNU httptunnel,当SSH被block时的选择
  • 原文地址:https://www.cnblogs.com/bxd123/p/11335096.html
Copyright © 2011-2022 走看看