zoukankan      html  css  js  c++  java
  • bzoj3732: Network

    那就是最小生成树咯

    建树后用LCA求解即可。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,d,next;
    }a[31000];int len,last[21000];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    int Bin[30];
    int dep[21000],f[30][21000],mx[30][21000];
    void dfs(int x)
    {
        for(int i=1;Bin[i]<=dep[x];i++)
        {
            f[i][x]=f[i-1][f[i-1][x]];
            mx[i][x]=max(mx[i-1][x],mx[i-1][f[i-1][x]]);
        }
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=f[0][x])
            {
                dep[y]=dep[x]+1;
                f[0][y]=x;mx[0][y]=a[k].d;
                dfs(y);
            }
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        
        int ans=0;
        for(int i=25;i>=0;i--)
            if(dep[x]-dep[y]>=Bin[i])
                ans=max(ans,mx[i][x]), x=f[i][x];
        if(x==y)return ans;
        
        for(int i=25;i>=0;i--)
            if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])
                ans=max(ans,max(mx[i][x],mx[i][y])), x=f[i][x],y=f[i][y];
        return max(ans,max(mx[0][x],mx[0][y]));
    }
    
    struct edge
    {
        int x,y,d;
    }e[31000];
    bool cmp(edge n1,edge n2){return n1.d<n2.d;}
    int fa[21000];
    int findfa(int x)
    {
        if(fa[x]==x)return x;
        fa[x]=findfa(fa[x]);return fa[x];
    }
    int main()
    {
        Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2;
        
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d);
        sort(e+1,e+m+1,cmp);
        
        for(int i=1;i<=n;i++)fa[i]=i;
        int cnt=0;
        for(int i=1;i<=m;i++)
        {
            int fx=findfa(e[i].x),fy=findfa(e[i].y);
            if(fx!=fy)
            {
                fa[fx]=fy;
                ins(e[i].x,e[i].y,e[i].d);
                ins(e[i].y,e[i].x,e[i].d);
                cnt++;if(cnt==n-1)break;
            }
        }
        f[0][1]=0;mx[0][1]=0;
        dep[1]=1;dfs(1);
        for(int i=1;i<=k;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            printf("%d
    ",LCA(x,y));
        }
        return 0;
    }
  • 相关阅读:
    caioj 1914 & CH 0x20搜索(0x27A*)例题1:第K短路 Remmarguts'Date
    多项式的化简求法
    caioj 1715 表达式的转换
    HDU 2829 Lawrence
    山海经 (线段树)
    神奇的KMP
    浅谈zkw线段树(by Shine_hale)
    线段树补充
    浅谈线段树(by Shine_hale)
    k短路
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8692532.html
Copyright © 2011-2022 走看看