• 【BZOJ3732】 Network Kruskal+倍增lca


    Description

    给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。 
    图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

    现在有 K个询问 (1 < = K < = 15,000)。 
    每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Input

    第一行: N, M, K。 
    第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。 
    第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Output

     对每个询问,输出最长的边最小值是多少。

    Sample Input

    6 6 8
    1 2 5
    2 3 4
    3 4 3
    1 4 8
    2 5 7
    4 6 2
    1 2
    1 3
    1 4
    2 3
    2 4
    5 1
    6 2
    6 1

    Sample Output

    5
    5
    5
    4
    4
    7
    4
    5

    HINT

    1 <= N <= 15,000 

    1 <= M <= 30,000 

    1 <= d_j <= 1,000,000,000 

    1 <= K <= 15,000 

    Source

    找到一个最小生成树,然后lca就好。。。肉眼查错大法好。。
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define M 30010
     7 #define N 15010
     8 #define inf 0x7fffffff
     9 using namespace std;
    10 struct node1{int x,y,v;}d[M]; 
    11 struct node2{int next,v,to;}e[M];
    12 int n,m,k,cnt;
    13 int fa[N][20],fa_max[N][20],belong[N],dpt[N],head[N];
    14 inline int read() {char c; int ans=0; while ((c=getchar())==' ' || c=='
    ' || c=='
    '); ans=c-'0'; while (isdigit(c=getchar())) ans=ans*10+c-'0'; return ans;}
    15 bool cmp(node1 a,node1 b){return a.v<b.v;}
    16 void adde(int x,int y,int z) {cnt++; e[cnt].next=head[x]; head[x]=cnt; e[cnt].to=y; e[cnt].v=z;}
    17 int findfa(int x)
    18 {
    19     if (!belong[x] || belong[x]==x) return belong[x]=x;
    20     else return belong[x]=findfa(belong[x]);
    21 }
    22 void bfework(int x)
    23 {
    24     dpt[x]=dpt[fa[x][0]]+1;
    25     for (int i=head[x];i;i=e[i].next)
    26     {
    27         if (e[i].to==fa[x][0]) continue;
    28         fa[e[i].to][0]=x;
    29         fa_max[e[i].to][0]=e[i].v;
    30         bfework(e[i].to);
    31     }
    32 }
    33 int query(int x,int y)
    34 {
    35     int ans=-inf;
    36     if (dpt[x]<dpt[y]) swap(x,y);
    37     for (int i=14;~i;i--)
    38         if (dpt[fa[x][i]]>=dpt[y]) 
    39             ans=max(ans,fa_max[x][i]),x=fa[x][i];
    40     if (x==y) return ans;
    41     for (int i=14;~i;i--)
    42         if (fa[x][i]!=fa[y][i])
    43         {
    44             ans=max(max(fa_max[x][i],fa_max[y][i]),ans);
    45             x=fa[x][i];
    46             y=fa[y][i];
    47         }
    48     ans=max(max(fa_max[x][0],fa_max[y][0]),ans);
    49     return ans;
    50 }
    51 int main()
    52 {
    53     n=read(); m=read(); k=read();
    54     for (int i=1;i<=m;i++) {d[i].x=read(); d[i].y=read(); d[i].v=read();}
    55     sort(d+1,d+m+1,cmp);
    56     for (int i=1;i<=m;i++)
    57     {
    58         int fax=findfa(d[i].x),fay=findfa(d[i].y);
    59         if (fax!=fay)
    60         {
    61             belong[fax]=fay;
    62             adde(d[i].x,d[i].y,d[i].v);
    63             adde(d[i].y,d[i].x,d[i].v);
    64         }
    65     }
    66     bfework(1);
    67     for (int i=1;i<=14;i++)
    68         for (int j=1;j<=n;j++)
    69             fa[j][i]=fa[fa[j][i-1]][i-1],fa_max[j][i]=max(fa_max[j][i-1],fa_max[fa[j][i-1]][i-1]);
    70     for (int i=1;i<=k;i++)
    71     {
    72         int x,y;
    73         x=read(); y=read();
    74         printf("%d
    ",query(x,y));
    75     }
    76 //    for (int i=1;i<=n;i++) printf("%d ",dpt[i]);
    77 //    printf("%d ",fa_max[5][1]);
    78     return 0;
    79 }
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    css 颜色
    目标
    css单位
    自我介绍
    Grid Layout
    position
    【转】android源码分析之windowmanager (android悬浮窗口的实现)
    java线程池原理
    STM32 中断中调用freeRTOS API 需要注意的地方
    今天开通博客园啦~~~~
  • 原文地址:https://www.cnblogs.com/DMoon/p/5299093.html
Copyright © 2020-2023  润新知