• bzoj3732: Network--kruskal最小生成树+LCA


    这是一道写起来比较顺手的题目

    没有各种奇怪的细节,基本就是Kruskal和倍增LCA的模板。。

    题目大意:对于一个无向带权图,询问两点之间一条路,使得这条路上的最长边最小,输出最小最长边的的值

    那么既然要使最长边最短,我们可以先构造一棵最小生成树

    由于kruskal已经将边排了序了,所以对于这棵树,每条边都尽量最短了

    然后我们再进行lca求出两点路径上的最长边,即为答案

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn = 15010;
     6 struct node{
     7     int u,v,cost,next;    
     8 }e[maxn*4],et[maxn*2];
     9 int head[maxn],n,m,K,tot,logn,u,v;
    10 int f[maxn],dep[maxn],fa[maxn][22],mx[maxn][22];
    11 
    12 void insert(int u, int v, int c){
    13     e[++tot].u=u; e[tot].v=v; e[tot].cost=c; e[tot].next=head[u]; head[u]=tot;
    14 }
    15 
    16 bool cmp(node a, node b){
    17     return a.cost<b.cost;
    18 }
    19 
    20 int find(int x){
    21     return f[x]==x?x:f[x]=find(f[x]);
    22 }
    23 
    24 void MST(){
    25     for (int i=1; i<=n; i++) f[i]=i;
    26     for (int i=1; i<=m; i++){
    27         int fx=find(et[i].u), fy=find(et[i].v);
    28         if (fx!=fy){
    29             f[fy]=fx;
    30             insert(et[i].u,et[i].v,et[i].cost);
    31             insert(et[i].v,et[i].u,et[i].cost);
    32         }
    33     }
    34 }
    35 
    36 void dfs(int u, int f, int d, int cost){
    37     dep[u]=d; fa[u][0]=f; mx[u][0]=cost;
    38     for (int i=1; i<=logn; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
    39     for (int i=1; i<=logn; i++) mx[u][i]=max(mx[u][i-1],mx[fa[u][i-1]][i-1]);
    40     for (int i=head[u]; i!=-1; i=e[i].next)
    41         if (e[i].v!=f) dfs(e[i].v,u,d+1,e[i].cost);
    42 }
    43 
    44 int lca_max(int u, int v){
    45     int ans=0;
    46     if (dep[u]>dep[v]) swap(u,v);
    47     while (dep[u]<dep[v]){
    48         for (int i=logn; i>=0; i--)
    49             if (dep[u]<dep[fa[v][i]]){
    50                 ans=max(ans,mx[v][i]);
    51                 v=fa[v][i];
    52             }
    53         ans=max(ans,mx[v][0]);
    54         v=fa[v][0];
    55     }
    56     if (u==v) return ans;
    57     for (int i=logn; i>=0; i--){
    58         if (fa[u][i]!=fa[v][i]){
    59             ans=max(ans,max(mx[v][i],mx[u][i]));
    60             u=fa[u][i]; v=fa[v][i];
    61         }
    62     }
    63     ans=max(ans,max(mx[u][0],mx[v][0]));
    64     return ans;
    65 }
    66 
    67 int main(){
    68     scanf("%d%d%d", &n, &m, &K);
    69     tot=-1; memset(head,-1,sizeof(head));
    70     while ((1<<logn)<n) logn++;
    71     for (int i=1; i<=m; i++)
    72         scanf("%d%d%d", &et[i].u, &et[i].v, &et[i].cost);
    73     sort(et+1,et+1+m,cmp);
    74     MST();
    75     dfs(1,0,1,0);
    76     while (K--){
    77         scanf("%d%d", &u, &v);
    78         printf("%d
    ", lca_max(u,v));
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    查杀木马利器,clamav
    zabbix运行久了以后效率会变慢的原因分析
    oracle sqlplus
    3000价位电脑配置实践
    phpmyadmin 万能密码漏洞
    nginx 的防cc攻击
    减少tcp TIME_WAIT 的数量
    nginx平滑升级
    心太大
    CentOS5.2下安装mplayer
  • 原文地址:https://www.cnblogs.com/mzl0707/p/5531373.html
Copyright © 2020-2023  润新知