传送门

分析

次小生成树的求法有两种,最大众的一种是通过倍增LCA找环中最大边求解,而这里我介绍一种神奇的O(nlogn) 做法:

我们先建立最小生成树,因为我们用kruskal求解是边的大小已经按升序排列,所以相同情况下,先枚举的边一定更优,所以我们每一次暴力的找非树边所连两点的LCA,并在寻找过程中对经过的边染色同时将其加入并查集以防止其二次查询(为何只需查找一次之前已经说过),然后在最后,我们只需找出所染颜色所代表的边的权值减去被染色的边的权值的最小值即可。因为被染色的树边共有n-1条,所以此过程的复杂度是O(m),因此总复杂度即为快排复杂度O(mlogm)。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<cctype>
using namespace std;
long long fa[110000],tot,used[310000],f[110000],col[310000],dep[110000];
long long ari[110000],is[110000];
long long sum=1;
struct node{
    long long x,y,z;
}d[310000];
struct edge{
    long long from,to,nxt,w,id;
}e[610000];
long long head[610000];
void add(long long x,long long y,long long z,long long id){
    e[sum].to=y;
    e[sum].nxt=head[x];
    e[sum].w=z;
    e[sum].id=id;
    head[x]=sum++;
    e[sum].to=x;
    e[sum].nxt=head[y];
    e[sum].w=z;
    e[sum].id=id;
    head[y]=sum++;
    return;
}
bool cmp(const node &p,const node &q){
    return p.z<q.z;
}
long long sf(long long a){
    return fa[a]==a?a:fa[a]=sf(fa[a]);
}
void dfs(long long a,long long fat){
    long long i,j,k;
    for(i=head[a];i;i=e[i].nxt)
       if(e[i].to!=fat){
        dep[e[i].to]=dep[a]+1;
        f[e[i].to]=a;
        ari[e[i].to]=e[i].id;
        dfs(e[i].to,a);
    }
    return;
}
long long ff(long long a){
    return is[a]==a?a:is[a]=ff(is[a]);
}
void mer(long long u,long long v,long long c){
    u=ff(u),v=ff(v);
    while(u!=v){
        if(dep[u]<dep[v])swap(u,v);
        col[ari[u]]=c;
        is[u]=ff(f[u]);
        u=ff(u);
    }
    return;
}
int main(){
    //freopen("1.in","r",stdin);
    long long n,m,i,j,k;
    scanf("%lld%lld",&n,&m);
    for(i=1;i<=m;i++){
       scanf("%lld%lld%lld",&d[i].x,&d[i].y,&d[i].z);
    }
    //建最小生成树
    sort(d+1,d+m+1,cmp);
    long long cnt=0,p,q;
    for(i=1;i<=n;i++){
       fa[i]=i;
       f[i]=i;
       is[i]=i;
    }
    for(i=1;i<=m;i++){
        p=sf(d[i].x),q=sf(d[i].y);
        if(p!=q){
            cnt++;
            if(rand()%2)fa[p]=q;
              else fa[q]=p;        
            tot+=d[i].z;
            used[i]=1;
            add(d[i].x,d[i].y,d[i].z,i);
        }
        if(cnt==n-1)break;
    }
    //初始化,f表示父子关系,is用于新并查集
    dfs(1,0);
    for(i=1;i<=m;i++)
       if(!used[i]){
            mer(d[i].x,d[i].y,i);
       }
    //求答案
    long long ans=1000000007;
    for(i=1;i<=m;i++)
       if(used[i]){
            if(col[i]&&d[col[i]].z!=d[i].z)
              ans=min(ans,d[col[i]].z-d[i].z);
       }
    printf("%lld\n",ans+tot);
    return 0;
}

p4180 次小生成树的更多相关文章

  1. P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 倍增(LCA)+最小生成树 施工队挖断学校光缆导致断网1天(大雾) 考虑直接枚举不在最小生成树上的边.但是边权可能与最小生成树上的边相等,这样删 ...

  2. 【luogu P4180 严格次小生成树[BJWC2010]】 模板

    题目链接:https://www.luogu.org/problemnew/show/P4180 这个题卡树剖.记得开O2. 这个题inf要到1e18. 定理:次小生成树和最小生成树差距只有在一条边上 ...

  3. 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)

    洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...

  4. Luogu P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 题意 题目描述 小\(C\)最近学了很多最小生成树的算法,\(Prim\)算法.\(Kurskal\)算法.消圈算法等等.正当小\(C\)洋洋得 ...

  5. 洛谷P4180【Beijing2010组队】次小生成树Tree

    题目描述: 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还 ...

  6. P4180 [BJWC2010]严格次小生成树

    P4180 [BJWC2010]严格次小生成树 P4180 题意 求出一个无向联通图的严格次小生成树.严格次小生成树的定义为边权和大于最小生成树的边权和但不存在另一棵生成树的边权和在最小生成树和严格次 ...

  7. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  8. P4180 严格次小生成树[BJWC2010] Kruskal,倍增

    题目链接\(Click\) \(Here\). 题意就是要求一个图的严格次小生成树.以前被题面吓到了没敢做,写了一下发现并不难. 既然要考虑次小我们就先考虑最小.可以感性理解到一定有一种次小生成树,可 ...

  9. [Luogu P4180][BJWC 2010]严格次小生成树

    严格次小生成树,关键是“严格”,如果是不严格的其实只需要枚举每条不在最小生成树的边,如果得到边权和大于等于最小生成树的结束就行.原理就是因为Kruskal非常贪心,只要随便改一条边就能得到一个非严格的 ...

随机推荐

  1. 前端基础-CSS属性操作

    前端基础-CSS属性操作 css text 文本颜色:color 颜色属性被用来设置文字的颜色. 颜色是通过CSS最经常的指定: 十六进制值 - 如: #FF0000 一个RGB值 - 如: RGB( ...

  2. P3988 [SHOI2013]发牌

    题目 P3988 [SHOI2013]发牌 做法 我们切牌时的状态: 手玩几次后我们发现切\(K\)次牌就是求堆顶一下的\(K+1\)大值,套上主席树就好了 My complete code #inc ...

  3. centos web+mysql服务器的安全

    今天闲来无事,拿来X-Scan-v3.3 来扫描自己的服务器,开放端口有22,80,443,3306:3306端口被扫出来,呵呵,那可不得了: 一,屏蔽扫描器扫出3306端口,因为web和数据库是在同 ...

  4. MHA高可用集群安装配置

    4台服务器 192.168.136.128 主 192.168.136.129 从 192.168.136.130 从 192.168.136.131 管理服务器 一主2从,一管理,安装mysql并配 ...

  5. 程序以html形式发送邮件注意问题

    1.样式要写在内部,不要单独定义样式 2.div 使用背景图片在有些浏览器中出不来这时候需要用: <table style="width: 640px" cellpaddin ...

  6. 分享知识-快乐自己:ActiveMQ 安装部署

    1):下载 ActiveMQ tar 包 2):上传到 服务器中 3):解压到 指定目录中 [root@admin tools]# tar -zxvf apache-activemq-5.2.0-bi ...

  7. 高并发下用pdo,文件排它锁,redis三种方法对比

    <?php header('content-type:text/html;charset=utf-8');                 // //无控制     // $DB_DSN = ' ...

  8. Java自定义分页标签的实现

    主要字段含义: 页号 pagaNo页面大小 pageSize总记录条数 recordCount计算本次一共分多少页 myPageSize页号显示开始 start 页号显示结束 end PageTag需 ...

  9. 【遍历二叉树】08判断两个二叉树是否相同【Same Tree】

    迭代版本用的是二叉树的DFS,中的root->right->left +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  10. Arc076_E Connected?

    传送门 题目大意 给定$H\times W$的网格$(W,H\leq 10^8)$上的$N$对顶点,即两线交叉的交叉点而非格子内部$(N\leq 10^5)$,求是否存在至少一种方案使得每对点之间都有 ...