TM终于过了。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 300500
#define maxe 800500
#define inf 0x7fffffffffffffff
using namespace std;
struct edge
{
long long v,w,nxt;
}e[maxe];
struct edge_mp
{
long long u,v,w,flag;
}mp[maxe];
long long n,m,g[maxv],nume=,father[maxv],anc[maxv][],mx1[maxv][],mx2[maxv][],ans=,dx=inf,dis[maxv];
long long r1=,r2=;
bool cmp(edge_mp x,edge_mp y)
{
return x.w<y.w;
}
void addedge(long long u,long long v,long long w)
{
e[++nume].v=v;
e[nume].w=w;
e[nume].nxt=g[u];
g[u]=nume;
}
long long getfather(long long x)
{
if (father[x]!=x)
father[x]=getfather(father[x]);
return father[x];
}
void kruskal()
{
for (long long i=;i<=n;i++) father[i]=i;
sort(mp+,mp+m+,cmp);
for (long long i=;i<=m;i++)
{
long long u=mp[i].u,v=mp[i].v,w=mp[i].w;
if (getfather(u)!=getfather(v))
{
father[getfather(u)]=getfather(v);mp[i].flag=;ans+=w;
addedge(u,v,w);addedge(v,u,w);
}
}
}
void dfs(long long x,long long father)
{
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if (v!=father)
{
anc[v][]=x;mx1[v][]=e[i].w;mx2[v][]=;
dis[v]=dis[x]+;
dfs(v,x);
}
}
}
void get_table()
{
for (long long e=;e<=;e++)
for (long long i=;i<=n;i++)
{
anc[i][e]=anc[anc[i][e-]][e-];
long long regis[];
regis[]=mx1[i][e-];regis[]=mx1[anc[i][e-]][e-];
regis[]=mx2[i][e-];regis[]=mx2[anc[i][e-]][e-];
sort(regis+,regis+);
mx1[i][e]=regis[];
for (long long j=;j>=;j--)
{
if (regis[j]==regis[j+]) continue;
else {mx2[i][e]=regis[j];break;}
}
}
} void get_ans(long long x)
{
long long u=mp[x].u,v=mp[x].v;r1=-;r2=-;
long long k1=-,k2=-,k3=-,k4=-;
if (dis[u]<dis[v]) swap(u,v);
if (dis[u]!=dis[v])
{
for (long long e=;e>=;e--)
{
long long pos=anc[u][e];
if ((dis[pos]>=dis[v]) && (pos>))
{
long long regis[];
regis[]=mx1[u][e];regis[]=mx2[u][e];regis[]=k1;regis[]=k2;
sort(regis+,regis+);
k1=regis[];
for (long long i=;i>=;i--)
{
if (regis[i]==regis[i+]) continue;
else {k2=regis[i];break;}
}
u=pos;
}
}
}
if (u==v)
{
r1=k1;r2=k2;
return;
}
for (long long e=;e>=;e--)
{
long long posu=anc[u][e],posv=anc[v][e];
if (posu!=posv)
{
long long regis[];
regis[]=mx1[u][e];regis[]=mx2[u][e];regis[]=k1;regis[]=k2;
sort(regis+,regis+);
k1=regis[];
for (long long i=;i>=;i--)
{
if (regis[i]==regis[i+]) continue;
else {k2=regis[i];break;}
}
regis[]=mx1[v][e];regis[]=mx2[v][e];regis[]=k3;regis[]=k4;
sort(regis+,regis+);
k3=regis[];
for (long long i=;i>=;i--)
{
if (regis[i]==regis[i+]) continue;
else {k4=regis[i];break;}
}
u=posu;v=posv;
}
}
long long regis[];
regis[]=k1;regis[]=k2;regis[]=k3;regis[]=k4;regis[]=mx1[u][];regis[]=mx1[v][];
sort(regis+,regis+);
r1=regis[];
for (long long i=;i>=;i--)
{
if (regis[i]==regis[i+]) continue;
else {r2=regis[i];break;}
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for (long long i=;i<=m;i++)
{
scanf("%lld%lld%lld",&mp[i].u,&mp[i].v,&mp[i].w);
mp[i].flag=;
}
kruskal();
memset(mx1,,sizeof(mx1));
memset(mx2,,sizeof(mx2));
dfs(,);
get_table();
for (long long i=;i<=m;i++)
{
if (mp[i].flag) continue;
long long u=mp[i].u,v=mp[i].v,w=mp[i].w;
get_ans(i);
if (r1==mp[i].w)
{
if (r2==-) continue;
dx=min(dx,mp[i].w-r2);
}
else if (r1<mp[i].w) dx=min(dx,mp[i].w-r1);
}
printf("%lld\n",ans+dx);
return ;
}

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

  1. [BeiJing2010组队][BZOJ 1977]次小生成树 Tree

    话说这个[BeiJing2010组队]是个什喵玩意? 这是一道严格次小生成树,而次小生成树的做法是层出不穷的 MATO IS NO.1 的博客里对两种算法都有很好的解释,值得拥有:  (果然除我以外, ...

  2. BZOJ 1977 次小生成树(最近公共祖先)

    题意:求一棵树的严格次小生成树,即权值严格大于最小生成树且权值最小的生成树. 先求最小生成树,对于每个不在树中的边,取两点间路径的信息,如果这条边的权值等于路径中的权值最大值,那就删掉路径中的次大值, ...

  3. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  4. BZOJ 1977 严格次小生成树(算竞进阶习题)

    树上倍增+kruskal 要找严格次小生成树,肯定先要找到最小生成树. 我们先把最小生成树的边找出来建树,然后依次枚举非树边,容易想到一种方式: 对于每条非树边(u,v),他会与树上的两个点构成环,我 ...

  5. BZOJ 1977[BeiJing2010组队]次小生成树 Tree - 生成树

    描述: 就是求一个次小生成树的边权和 传送门 题解 我们先构造一个最小生成树, 把树上的边记录下来. 然后再枚举每条非树边(u, v, val),在树上找出u 到v 路径上的最小边$g_0$ 和 严格 ...

  6. 【刷题】BZOJ 1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

  7. BZOJ 1977 严格次小生成树

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

  8. bzoj 1977 洛谷P4180 严格次小生成树

    Description: 给定一张N个节点M条边的无向图,求该图的严格次小生成树.设最小生成树边权之和为sum,那么严格次小生成树就是边权之和大于sum的最小的一个 Input: 第一行包含两个整数N ...

  9. 1977: [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...

随机推荐

  1. UITbaleView上按钮的单选

    设置Id属性,标记是哪个cell @property (nonatomic,assign)NSInteger Id; 设置一个普通状态和选中状态图片不同的按钮 _choose = [[UIButton ...

  2. CSS Ruler 前端工具

    CSS Ruler是一款在线的CSS单位工具. CSS Ruler 彩蛋爆料直击现场 http://katydecorah.com/css-ruler/

  3. 深入浅出ES6(十四):let和const

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 回溯到1995年,当Brendan Eich在设计第一版JavaScript时, ...

  4. mvc5 知识点01

    1.ViewBag 动态数据类型,也就是说可以随便指定属性,前后台传值很是有用 2.Layout 属性,定义模版,模版中一般用@RenderBody() 做占位符,用于放置子页面内容 3.@model ...

  5. WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).

    WCF除了支持经典的请求应答(Request-Reply)模式外,还提供了什么操作调用模式,他们有什么不同以及我们如何在开发中使用这些操作调用模式.今天本节文章里会详细介绍.WCF分布式开发步步为赢( ...

  6. Codeforces Round #335 (Div. 2) A. Magic Spheres 模拟

    A. Magic Spheres   Carl is a beginner magician. He has a blue, b violet and c orange magic spheres. ...

  7. Jquery DataTables warning : Requested unknown from the data source for row 0

    昨天在做 Jquery DataTables 的时候,遇到的一个问题,我使用MVC,在tables上加入了一个actionlink的href.但是在运行起来的时候,报错: DataTables war ...

  8. iOS开发--CoreGraphics简单绘图

    一.导入coreGraphics.framework 二.绘制图形 1.绘制矩形 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // 绘制矩形 - (v ...

  9. 修改图层的symbol(AE+C#)

    取出一个图层的symbol 在其基础上对其进行修改 private void button1_Click(object sender, EventArgs e)        {  mp;nbsp;  ...

  10. 5、java反射基础

    Class对象: Class对象记录了所有与类相关的信息,当类加载器从文件系统中加载.class文件到JVM中的同时会为每一个类创建一个Class对象.通过Class对象可以获取到类的属性.方法.构造 ...