• [BJOI 2010]次小生成树Tree


    Description

    小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足:(value(e) 表示边 e的权值)  这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

    Input

    第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

    Output

    包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

    Sample Input

    5 6
    1 2 1
    1 3 2
    2 4 3
    3 5 4
    3 4 3
    4 5 6

    Sample Output

    11

    Hint

    数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

    题解

    次小生成树模板。简便地直接用$LCA$做。唯一注意的是由于它要求严格的次小生成树,所以我们$LCA$时还要记得保存次大值。(防止边权相等)

      1 #include<map>
      2 #include<cmath>
      3 #include<ctime>
      4 #include<queue>
      5 #include<stack>
      6 #include<cstdio>
      7 #include<string>
      8 #include<cstring>
      9 #include<cstdlib>
     10 #include<iostream>
     11 #include<algorithm>
     12 #define LL long long
     13  using namespace std;
     14 const LL N=100000;
     15 
     16 LL n,m,op,x,y,p,q,d=2e15;
     17 struct aa
     18 {
     19     LL u,v,c;
     20 }lin[N*3+5];
     21 bool comp(aa a,aa b);
     22 
     23 LL mst,cnt;
     24 struct bb
     25 {
     26     LL to,next,cost;
     27 }edge[N*2+5];
     28 LL path[N+5],top;
     29 bool vis[N*3+5];
     30 void Add(LL u,LL v,LL c);
     31 
     32 LL set[N+5];
     33 LL Find(LL x);
     34 
     35 LL f[N+5][20],maxn[N+5][20],sub[N+5][20];
     36 LL dep[N+5];
     37 void Dfs(LL x,LL depth);
     38 void Lca(LL x,LL y,LL c);
     39 
     40 int main()
     41 {
     42     scanf("%lld%lld",&n,&m);
     43     op=log2(n);
     44     for (LL i=1;i<=m;i++) scanf("%lld%lld%lld",&lin[i].u,&lin[i].v,&lin[i].c);
     45     sort(lin+1,lin+m+1,comp);
     46     for (LL i=1;i<=m;i++)
     47     {
     48         p=Find(lin[i].u);
     49         q=Find(lin[i].v);
     50         if (p!=q)
     51         {
     52             set[p]=q;
     53             cnt++;
     54             mst+=lin[i].c;
     55             vis[i]=1;
     56             Add(lin[i].u,lin[i].v,lin[i].c);
     57             Add(lin[i].v,lin[i].u,lin[i].c);
     58             if (cnt==n-1) break;
     59         }
     60     }
     61     if (cnt<n-1)
     62     {
     63         printf("No MST!
    ");
     64         return 0;
     65     }
     66     Dfs(1,1);
     67     for (LL t=1;t<=op;t++)
     68         for (LL i=1;i<=n;i++)
     69             if (f[i][t-1])
     70             {
     71                 f[i][t]=f[f[i][t-1]][t-1];
     72                 x=maxn[i][t-1];y=sub[i][t-1];
     73                 p=maxn[f[i][t-1]][t-1];q=sub[f[i][t-1]][t-1];
     74                 if (x==p){maxn[i][t]=x;sub[i][t]=max(y,q);}
     75                 else if (x>p){maxn[i][t]=x;sub[i][t]=max(p,y);}
     76                 else if (x<p){maxn[i][t]=p;sub[i][t]=max(x,q);}
     77             }
     78     for (LL i=1;i<=m;i++) if (!vis[i]) Lca(lin[i].u,lin[i].v,lin[i].c);
     79     if (d==2e15) printf("No SST!");
     80     else printf("%lld
    ",mst+d);
     81     return 0;
     82 }
     83 
     84 bool comp(aa a,aa b){return a.c<b.c;}
     85 void Add(LL u,LL v,LL c)
     86 {
     87     edge[++top].to=v;
     88     edge[top].next=path[u];
     89     edge[top].cost=c;
     90     path[u]=top;
     91 }
     92 LL Find(LL x){return set[x] ? set[x]=Find(set[x]):x;}
     93 void Dfs(LL x,LL depth)
     94 {
     95     dep[x]=depth;
     96     for (LL i=path[x];i;i=edge[i].next) if (!dep[edge[i].to])
     97     {
     98         f[edge[i].to][0]=x;
     99         maxn[edge[i].to][0]=edge[i].cost;
    100         Dfs(edge[i].to,depth+1);
    101     }
    102 }
    103 void Lca(LL x,LL y,LL c)
    104 {
    105     LL m1=0,m2=0;
    106     if (dep[x]<dep[y]) swap(x,y);
    107     for (LL i=op;i>=0;i--) if (dep[x]-(1<<i)>=dep[y])
    108     {
    109         if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}
    110         else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];
    111         if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}
    112         else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];
    113         x=f[x][i];
    114     }
    115     if (x!=y)
    116     {
    117         for (LL i=op;i>=0;i--) if (f[x][i]!=f[y][i])
    118         {
    119             if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}
    120             else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];
    121             if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}
    122             else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];
    123             if (sub[y][i]>m1){m2=m1;m1=sub[y][i];}
    124             else if (sub[y][i]>m2&&sub[y][i]!=m1) m2=sub[y][i];
    125             if (maxn[y][i]>m1){m2=m1;m1=maxn[y][i];}
    126             else if (maxn[y][i]>m2&&maxn[y][i]!=m1) m2=maxn[y][i];
    127             x=f[x][i];
    128             y=f[y][i];
    129         }
    130         if (sub[x][0]>m1){m2=m1;m1=sub[x][0];}
    131         else if (sub[x][0]>m2&&sub[x][0]!=m1) m2=sub[x][0];
    132         if (maxn[x][0]>m1){m2=m1;m1=maxn[x][0];}
    133         else if (maxn[x][0]>m2&&maxn[x][0]!=m1) m2=maxn[x][0];
    134         if (sub[y][0]>m1){m2=m1;m1=sub[y][0];}
    135         else if (sub[y][0]>m2&&sub[y][0]!=m1) m2=sub[y][0];
    136         if (maxn[y][0]>m1){m2=m1;m1=maxn[y][0];}
    137         else if (maxn[y][0]>m2&&maxn[y][0]!=m1) m2=maxn[y][0];
    138     }
    139     if (m1==0) return;
    140     if (c==m1)
    141     {
    142         if (m2==0) return;
    143         d=min(d,c-m2);
    144     }
    145     else d=min(d,c-m1);
    146 }
    博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/NaVi-Awson/,否则你会终生找不到妹子!!!
  • 相关阅读:
    DedeCMS系统301重定向配置方法详解
    dedecms批量更新静态时提示:没有该栏目数据 可能缓存的解决方法
    修改织梦dedecms后台默认admin账号的方法
    织梦DeDeCMS动态热点文章排行调用方法
    文件与字符串处理时常见的问题(中文英文)
    基于OpenCV全景拼接(Python)SIFT/SURF
    解决关闭ssh后网页停止服务的方法,利用nohup
    解决宝塔面板没有命令行问题 && 查看宝塔面板项目环境
    python 正则表达式
    JAVAC 不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7252318.html
Copyright © 2020-2023  润新知