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. JSP 页面打印

    <HTML><HEAD><TITLE>javascript打印-打印页面设置-打印预览代码</TITLE> <META http-equiv=Co ...

  2. HDU3341 Lost's revenge(AC自动机&&dp)

    一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...

  3. POJ 3685

    Matrix Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 4428   Accepted: 1102 Descriptio ...

  4. 《Thinking in C++》学习笔记(二)【第三章】

    第三章 C++中的C 3.4.4 指针简介 ‘&’运算符:只要在标识符前加上‘&’,就会得出标识符的地址. C和C++有一个专门存放地址的变量类型.这个变量类型叫做指针(pointer ...

  5. UVA 10943 How do you add? DP

    Larry is very bad at math — he usually uses a calculator, whichworked well throughout college. Unfor ...

  6. 【BZOJ1878】[SDOI2009]HH的项链 离线BIT

    1878: [SDOI2009]HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...

  7. Jenkins配置基于角色的项目权限管理--转

    本文将介绍如何配置jenkins,使其可以支持基于角色的项目权限管理. 由于jenkins默认的权限管理体系不支持用户组或角色的配置,因此需要安装第三发插件来支持角色的配置,本文将使用Role Str ...

  8. ls 知识点

    ls -R 将会以目录的形式列出所有文件,-S 以文件的大小列出所有文件,-t 将会按照修改时间来列出文件,-i 会显示文件的inode

  9. 斐波那契数列公式算法-JS实现

    之前算斐波那契数列都是算前两个数相加实现的 比如0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181 ...

  10. hadoop 2.0 native

    1.安装protobuf,参照http://wiki.apache.org/hadoop/HowToContribute 安装java模块 在java目录mvn install 2.配置protobu ...