题意:求一棵树的严格次小生成树,即权值严格大于最小生成树且权值最小的生成树。

先求最小生成树,对于每个不在树中的边,取两点间路径的信息,如果这条边的权值等于路径中的权值最大值,那就删掉路径中的次大值,加上这条非树边,更新答案;否则删掉路径中的最大值,加上这条非树边,更新答案。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define ll long long
struct edge{
int u,v,id;
ll w;
}e[];
int tot,go[],first[],next[];
ll val[];
int fa[][],deep[],F[],bin[],n,m;
ll mx1[][],mx2[][],ans1,ans2;
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
ll Read(){
char ch=getchar();ll t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
bool cmp(edge a,edge b){
return a.w<b.w;
}
void insert(int x,int y,ll z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
val[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);insert(y,x,z);
}
int find(int x){
if (F[x]==x) return x;
else return (find(F[x]));
}
void up(ll x,ll &y){
if (x>y) y=x;
}
void work(int x,int i){
mx1[x][i]=std::max(mx1[fa[x][i-]][i-],mx1[x][i-]);
if (mx1[fa[x][i-]][i-]<mx1[x][i]) up(mx1[fa[x][i-]][i-],mx2[x][i]);
if (mx1[x][i-]<mx1[x][i]) up(mx1[x][i-],mx2[x][i]);
up(mx2[x][i-],mx2[x][i]);
up(mx2[fa[x][i-]][i-],mx2[x][i]);
}
void dfs(int x,int f){
for (int i=;i<=;i++)
fa[x][i]=fa[fa[x][i-]][i-],work(x,i);
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==f) continue;
deep[pur]=deep[x]+;
fa[pur][]=x;
mx1[pur][]=val[i];
mx2[pur][]=;
dfs(pur,x);
}
}
void up(ll x,ll &a,ll &b){
if (x>a) b=a,a=x;
else
if (x>b&&x<a) b=x;
}
void lca(int x,int y){
ans1=,ans2=;
if (deep[x]<deep[y]) std::swap(x,y);
int t=deep[x]-deep[y];
for (int i=;i<=;i++)
if (t&bin[i]) {
up(mx1[x][i],ans1,ans2);
up(mx2[x][i],ans1,ans2);
x=fa[x][i];
}
for (int i=;i>=;i--)
if (fa[x][i]!=fa[y][i]) {
up(mx1[x][i],ans1,ans2);
up(mx2[x][i],ans1,ans2);
up(mx1[y][i],ans1,ans2);
up(mx2[y][i],ans1,ans2);
x=fa[x][i];
y=fa[y][i];
}
if (x!=y){
up(mx1[x][],ans1,ans2);
up(mx2[x][],ans1,ans2);
up(mx1[y][],ans1,ans2);
up(mx2[y][],ans1,ans2);
}
}
int main(){
bin[]=;
for (int i=;i<=;i++) bin[i]=bin[i-]*;
n=read();m=read();
for (int i=;i<=m;i++){
e[i].u=read();
e[i].v=read();
e[i].w=Read();
e[i].id=;
}
for (int i=;i<=n;i++)
for (int j=;j<=;j++)
mx1[i][j]=mx2[i][j]=;
std::sort(e+,e++m,cmp);
ll sum=;
for (int i=;i<=n;i++) F[i]=i;
for (int i=;i<=m;i++)
if (find(e[i].u)!=find(e[i].v)){
F[find(e[i].u)]=find(e[i].v);
e[i].id=;
add(e[i].u,e[i].v,e[i].w);
sum+=e[i].w;
}
dfs(,);
ll Ans=10000000000000000LL;
for (int i=;i<=m;i++)
if (!e[i].id){
lca(e[i].u,e[i].v);
if (e[i].w==ans1) Ans=std::min(Ans,sum-ans2+e[i].w);
else Ans=std::min(Ans,sum-ans1+e[i].w);
}
printf("%lld\n",Ans);
}

BZOJ 1977 次小生成树(最近公共祖先)的更多相关文章

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

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

  2. BZOJ 1977 次小生成树

    TM终于过了.... #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  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. POST多个参数到Web API控制器

    交互基于Json的方式打包传递就不介绍了,主要设置请求头为 contentType: "application/json", //必须有 数据位Json格式的字符串,在服务器端定义 ...

  2. fuck WPFG.org

    今天一旦进入国外网站,就立刻跳转到WPFG.org.可能DNS被劫持污染了吧.用OpenDNS就行了.然后就没有这回事发生了 参考以下: https://www.opendns.com https:/ ...

  3. EBS Workfow常用表

    1.Workflow Definition Tables WF_ITEM_TYPES WF_ACTIVITIES WF_MESSAGES WF_ITEM_ATTRIBUTES WF_ACTIVITY_ ...

  4. java算法之身份证号码验证

    调用时直接 new IDCard().verify(身份证id);就可以了 实现代码如下: public class IDCard { private String _codeError; //wi ...

  5. C# - 使用ConfigurationManager保存数据到App.config

    1. ConfigurationManager的命名空间:using System.Configuration; 2. To be able to save you have to use a con ...

  6. poj 1274 The Perfect Stall(二分图匹配)

    Description Farmer John completed his new barn just last week, complete with all the latest milking ...

  7. poj 3187 Backward Digit Sums(穷竭搜索dfs)

    Description FJ and his cows enjoy playing a mental game. They write down the numbers to N ( <= N ...

  8. AIX下RAC搭建 Oracle10G(一)检測系统环境

    AIX下RAC搭建系列 环境 节点 节点1 节点2 小机型号 IBM P-series 630 IBM P-series 630 主机名 AIX203 AIX204 交换机 SAN光纤交换机 存储 S ...

  9. [Redux] Extracting Container Components (FilterLink)

    Learn how to avoid the boilerplate of passing the props down the intermediate components by introduc ...

  10. Android模仿jquery异步请求

    01 package com.xbl.task; 02   03 import java.io.BufferedReader; 04 import java.io.InputStream; 05 im ...