zoukankan      html  css  js  c++  java
  • BZOJ 3732: Network 最小生成树 倍增

    3732: Network

    题目连接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=3732

    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

    题意

    题解:

    我一开始竟然在想一个好傻的问题:生成一棵最长边最小的树,可不可以保证任意两点之间最长边最小。(最小生成树没学好的结果)

    这题比较裸,先生成最小生成树,然后倍增求两点路径最长边。

    当然树链剖分也行,感觉树剖也挺容易打的。

    Debug

    1.n,m混用,导致最小生成树写错了。

    2.数组开小了,点和边应该分开开数组。

    3.倍增时,如果调整高度相同时,如果x==y,要直接返回答案。

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define N 40050
      5 int n,m,dp[N],mx[N][15],fu[N][15],mm[N];
      6 int tot,last[N];
      7 struct Edge
      8 {
      9     int from,to,val,s;
     10     bool operator <(const Edge&b)const 
     11         {return val<b.val;}
     12 }a[N],edges[N<<1];
     13 template<typename T>void read(T&x)
     14 {
     15     ll k=0; char c=getchar();
     16     x=0;
     17     while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
     18     if (c==EOF)exit(0);
     19     while(isdigit(c))x=x*10+c-'0',c=getchar();
     20     x=k?-x:x;
     21 }
     22 void read_char(char &c)
     23 {while(!isalpha(c=getchar())&&c!=EOF);}
     24 void AddEdge(int x,int y,int z)
     25     {
     26         edges[++tot]=Edge{x,y,z,last[x]};
     27         last[x]=tot;
     28     }
     29 int gf(int x,int *fa)
     30 {
     31     if(x==fa[x])return x;
     32     return fa[x]=gf(fa[x],fa);
     33 }
     34 void MST(Edge *edges)
     35 {
     36     static Edge a[N];
     37     static int fa[N];
     38     for(int i=1;i<=m;i++)a[i]=edges[i];
     39     for(int i=1;i<=n;i++)fa[i]=i;//
     40     sort(a+1,a+m+1);
     41     int num=0;
     42     for(int i=1;i<=m;i++)//
     43     {
     44         int fx=gf(a[i].from,fa),fy=gf(a[i].to,fa);
     45         if (fx==fy)continue;
     46         AddEdge(a[i].from,a[i].to,a[i].val);
     47         AddEdge(a[i].to,a[i].from,a[i].val);
     48         fa[fx]=fy;
     49         if (++num==n-1)break;
     50     }
     51 }
     52 void dfs(int x,int pre)
     53 {
     54     fu[x][0]=pre;
     55     dp[x]=dp[pre]+1;
     56     for(int i=last[x];i;i=edges[i].s)
     57     {
     58         Edge &e=edges[i];
     59         if (e.to==pre)continue;
     60         mx[e.to][0]=e.val;
     61         dfs(e.to,x);
     62     }
     63 }
     64 void init_ST()
     65 {
     66     for(int i=2;i<=n;i++)mm[i]=mm[i>>1]+1;
     67     for(int i=1;i<=14;i++)
     68         for(int j=1;j<=n;j++)//
     69         {
     70             fu[j][i]=fu[fu[j][i-1]][i-1];
     71             mx[j][i]=max(mx[j][i-1],mx[fu[j][i-1]][i-1]);
     72         }
     73 }
     74 int GetLca(int x,int y)
     75 {
     76     int ans=0;
     77     if (dp[x]<dp[y])swap(x,y);
     78     int k=mm[dp[x]-dp[y]];//
     79     for(int i=k;i>=0;i--)
     80         if (dp[fu[x][i]]>=dp[y])
     81         {
     82             ans=max(ans,mx[x][i]);
     83             x=fu[x][i];
     84         }
     85     if (x==y)return ans;//
     86     k=mm[dp[x]-1];
     87     for(int i=k;i>=0;i--)
     88         if (fu[x][i]!=fu[y][i])
     89         {
     90             ans=max(ans,mx[x][i]);
     91             ans=max(ans,mx[y][i]);
     92             x=fu[x][i];
     93             y=fu[y][i];
     94         }
     95     ans=max(ans,mx[x][0]);
     96     ans=max(ans,mx[y][0]);
     97     return ans;
     98 }
     99 int main()
    100 {
    101 #ifndef ONLINE_JUDGE
    102     freopen("aa.in","r",stdin);
    103 #endif
    104     int q;
    105     read(n); read(m); read(q);
    106     for(int i=1;i<=m;i++)
    107     {
    108         int x,y,z;
    109         read(x); read(y); read(z);
    110         a[i]=Edge{x,y,z,0};
    111     }
    112     MST(a);
    113     dfs(1,0);
    114     init_ST();
    115     for(int i=1;i<=q;i++)
    116     {
    117         int x,y;
    118         read(x); read(y);
    119         printf("%d
    ",GetLca(x,y));
    120     }
    121 }
    View Code
  • 相关阅读:
    每天一个linux命令(54):sftp命令
    每天一个linux命令(53):wget命令
    每天一个linux命令(52):scp命令
    每天一个linux命令(51):rcp命令
    每天一个linux命令(50):telnet命令
    每天一个linux命令(49):ss命令
    每天一个linux命令(48):netstat命令
    每天一个linux命令(46):ping命令
    Springmvc常见问题
    MP实战系列(十)之SpringMVC集成SpringFox+Swagger2
  • 原文地址:https://www.cnblogs.com/mmmqqdd/p/10837722.html
Copyright © 2011-2022 走看看