传送门

分析

次小生成树的求法有两种,最大众的一种是通过倍增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. Spark Structured Streaming框架(3)之数据输出源详解

    Spark Structured streaming API支持的输出源有:Console.Memory.File和Foreach.其中Console在前两篇博文中已有详述,而Memory使用非常简单 ...

  2. 3D卡片折叠动画自定义下拉框

    在线演示 本地下载

  3. hd acm1466

    http://www.cnblogs.com/alihenaixiao/p/4107907.html#undefined.这个博客有详解,我这个只是写一些·自己的总结. 问题:平面上有n条直线,且无三 ...

  4. 在ubuntu上为android系统编写Linux驱动程序【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/6568411 在智能手机时代,每个品牌的手机都有自己的个性特点.正是依靠这种与众不同的 ...

  5. 手撸IoC

    Ioc的实现 可以把IoC模式看作是工厂模式的升华,可以把IoC看作一个大工厂,只不过这个大工厂里要生成的对象都是XML文件中给出定义的,然后利用Java的反射变成,根据XML中给出的类名生成相应的对 ...

  6. 算法(Algorithms)第4版 练习 2.2.11(最终)

    package com.qiusongde; import edu.princeton.cs.algs4.In; import edu.princeton.cs.algs4.StdOut; publi ...

  7. django中使用多个数据库,跨库查询

    一.settings配置多个数据库 DATABASES = { 'default': { # 'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'comm ...

  8. Java企业微信开发_03_自定义菜单

    一.本节要点 1.菜单相关实体类的封装 参考官方文档中的请求包的内容,对菜单相关实体类进行封装. 这里需要格外注意的是,企业微信中请求包的数据是Json字符串格式的,而不是xml格式.关于json序列 ...

  9. IO流 相关基础积累

    一个整型32位字节. 写入到流.? 为什么要按十六进制输出到控制台?

  10. [原]NYOJ-房间安排168

    大学生程序代写 /*房间安排 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 2010年上海世界博览会(Expo2010),是第41届世界博览会.于2010年5月1日至1 ...