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. hdu5017 Ellipsoid(旋转)

    比赛的时候跳进这个大坑里,最后代码是写出来了.看到好像很多都是模拟退火做的,下面提供一个奇怪的思路吧. ax^2+by^2+cz^2+dyz+exz+fxy=1(*) 通过一些奇特的YY我们可以知道这 ...

  2. CodeIgniter 常量ENVIRONMENT设置要注意的地方

    http://bbs.phpchina.com/thread-274514-1-1.html index.php ,这是CodeIgniter的入口文件,做开发是,都会设置一下define('ENVI ...

  3. jquery select处理

    JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转.传参 js 处理 select :选中,删除,更改等 http://blog.csdn.net/wust_star/ ...

  4. ARM系列产品

    ARM7系列 ARM9系列 ARM9E系列 ARM10E系列 SecurCore系列 Intel的StrongARM ARM11系列 Intel的Xscale 其中,ARM7.ARM9.ARM9E和A ...

  5. Hortworks Hadoop生态圈简介

    Hortworks 作为Apache Hadoop2.0社区的开拓者,构建了一套自己的Hadoop生态圈,包括存储数据的HDFS,资源管理框架YARN,计算模型MAPREDUCE.TEZ等,服务于数据 ...

  6. sql openrowset

    select * from openrowset('sqloledb','ip';'user';'pwd','exec 库..过程') 

  7. ruby libmysqlclient.18.dylib

    在mac 的rails环境中,如果已经确定安装了 mysql server,但是在启动rails s (服务器)的时候出现  Library not loaded: libmysqlclient.18 ...

  8. ARM菜鸟:JLINK与JTAG的区别

    调试ARM,要遵循ARM的调试接口协议,JTAG就是其中的一种.当仿真时,IAR.KEIL.ADS等都有一个公共的调试接口,RDI就是其中的一种,那么我们如何完成RDI-->ARM调试协议(JT ...

  9. CentOS单用户模式下修改ROOT密码和grub加密

    Linux 系统处于正常状态时,服务器主机开机(或重新启动)后,能够由系统引导器程序自动引导 Linux 系统启动到多用户模式,并提供正常的网络服务.如果系统管理员需要进行系统维护或系统出现启动异常时 ...

  10. iOS:核心动画具体的类和协议的介绍

    核心动画类:CAAnimation.CAPropertyAnimation.CABasicAnimation.CAKeyframeAnimation.CATransition.CAAnimationG ...