zoukankan      html  css  js  c++  java
  • bzoj3732Network

    bzoj3732Network

    题意:

    给一个无向图,k个询问求节点a到节点b最长边的最小值。n,k≤15000。

    题解:

    ”最长边的最小值“经常可以用最小生成树解决,因为生成树里的每一条边都是可取的最小边,求完生成树之后就是经典的倍增应用:求lca的时候顺便维护一下边权最大值即可。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 30010
     7 using namespace std;
     8 
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;    
    14 }
    15 struct abc{int f,t,w;}abcd[maxn]; bool cmp(abc a,abc b){return a.w<b.w;}
    16 struct e{int t,w,n;}es[maxn*2]; int g[maxn],ess;
    17 void pe(int f,int t,int w){
    18     es[++ess]=(e){t,w,g[f]}; g[f]=ess; es[++ess]=(e){f,w,g[t]}; g[t]=ess;
    19 }
    20 int n,m,k,p[maxn],fa[20][maxn],mx[20][maxn],tot,dep[maxn];
    21 int find(int x){return x==p[x]?x:p[x]=find(p[x]);}
    22 void dfs(int x){
    23     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa[0][x])
    24         fa[0][es[i].t]=x,mx[0][es[i].t]=es[i].w,dep[es[i].t]=dep[x]+1,dfs(es[i].t);
    25 }
    26 int lca(int x,int y){
    27     if(dep[x]<dep[y])swap(x,y); int t=dep[x]-dep[y],ans=0;
    28     for(int i=0;(1<<i)<=n;i++)if(t&(1<<i))ans=max(ans,mx[i][x]),x=fa[i][x];
    29     for(int i=19;i>=0;i--)if(fa[i][x]!=fa[i][y])
    30         ans=max(ans,mx[i][x]),ans=max(ans,mx[i][y]),x=fa[i][x],y=fa[i][y];
    31     if(x==y)return ans;else{ans=max(ans,mx[0][x]); ans=max(ans,mx[0][y]); return ans;}
    32 }
    33 int main(){
    34     n=read(); m=read(); k=read(); inc(i,1,n)p[i]=i;
    35     inc(i,1,m){int x=read(),y=read(),z=read(); abcd[i]=(abc){x,y,z};} sort(abcd+1,abcd+m+1,cmp);
    36     inc(i,1,m){
    37         int x=find(abcd[i].f),y=find(abcd[i].t); if(x!=y)pe(x,y,abcd[i].w),p[x]=y,tot++; if(tot==n-1)break;
    38     }
    39     dfs(1);
    40     for(int i=1;(1<<i)<=n;i++)inc(j,1,n)
    41         fa[i][j]=fa[i-1][fa[i-1][j]],mx[i][j]=max(mx[i-1][j],mx[i-1][fa[i-1][j]]);
    42     inc(i,1,k){int x=read(),y=read(); printf("%d
    ",lca(x,y));}
    43     return 0;
    44 }

    20161115

  • 相关阅读:
    cf B. Number Busters
    hdu 5072 Coprime
    HDOJ迷宫城堡(判断强连通 tarjan算法)
    Entropy (huffman) 优先队列)
    Number Sequence
    Code (组合数)
    Round Numbers (排列组合)
    Naive and Silly Muggles (计算几何)
    SDUT 最短路径(二维SPFA)
    Pearls DP
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/6067495.html
Copyright © 2011-2022 走看看