题目链接

题意如题。

这题作为我们KS图论的T4,我直接打了个很暴力的暴力,骗了20分。。

当然,我们KS里的数据范围远不及这题。

这题我debug了整整一个晚上还没debug出来,第二天早上眼前一亮,改出来了。

严格次小生成树,顾名思义,就是数值严格小于最小生成树的最大生成树。

\(\text{邓杰:一个很暴力的方法就是,求出最小生成树后,枚举不在生成树里的边,把这条边加进去,然后就会形成一个环,把这个环里最大的边删掉,然后对新形成的生成树取最小值}\)

其实正解应该是吧就是对这个“暴力”的优化。这个“环”其实去掉加的边后就是原数中这条边连接的两个点之间的路径,统计最大值就行了。由于是 严格 次小生成树,所以还要维护一个次大值。链上求最值,这个显然可以用树剖来实现,但此题是静态链上求最值,直接用倍增来维护就行了,具体的就在倍增跳LCA的时候统计最值就行了。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define INF 2147483647
#define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
#define Close fclose(stdin); fclose(stdout);
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s * w;
}
typedef long long ll;
const int MAXN = 100010;
const int MAXM = 300010;
struct edge{
int from, to, dis;
bool operator < (const edge A) const{
return dis < A.dis;
}
}s[MAXM];
struct Edge{
int to, next, dis;
}e[MAXN];
int num, head[MAXN << 1];
inline void Add(int from, int to, int dis){
e[++num] = (Edge){ to, head[from], dis };
head[from] = num;
}
int n, m;
ll ans;
int fa[MAXN], t[MAXN], flag, f[MAXN][23], dep[MAXN];
ll Max[MAXN][23], SMax[MAXN][23];
void init(){
for(int i = 1; i <= n; ++i) fa[i] = i;
}
int find(int x){
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y){
fa[find(y)] = find(x);
}
void DFS(int u, int fa){
dep[u] = dep[fa] + 1;
f[u][0] = fa;
for(int i = head[u]; i; i = e[i].next)
if(e[i].to != fa)
Max[e[i].to][0] = e[i].dis, DFS(e[i].to, u);
}
int LCA(int u, int v, int Ans){
ll MAX = 0, SMAX = 0;
if(dep[u] < dep[v]) swap(u, v);
int cha = dep[u] - dep[v];
for(int i = 21; i >= 0; --i)
if(cha & (1 << i)){
if(Max[u][i] > MAX){
SMAX = MAX;
MAX = Max[u][i];
}
else if(Max[u][i] != MAX && Max[u][i] > SMAX) SMAX = Max[u][i];
if(SMax[u][i] > SMAX) SMAX = SMax[u][i];
u = f[u][i];
}
for(int i = 21; i >= 0; --i)
if(f[u][i] != f[v][i]){
if(Max[u][i] > MAX){
SMAX = MAX;
MAX = Max[u][i];
}
else if(Max[u][i] != MAX && Max[u][i] > SMAX) SMAX = Max[u][i];
if(SMax[u][i] > SMAX) SMAX = SMax[u][i];
if(Max[v][i] > MAX){
SMAX = MAX;
MAX = Max[v][i];
}
else if(Max[v][i] != MAX && Max[v][i] > SMAX) SMAX = Max[v][i];
if(SMax[v][i] > SMAX) SMAX = SMax[v][i];
u = f[u][i], v = f[v][i];
}
if(u != v){
if(Max[v][0] > MAX){
SMAX = MAX;
MAX = Max[v][0];
}
else if(Max[v][0] != MAX && Max[v][0] > SMAX) SMAX = Max[v][0];
if(SMax[v][0] > SMAX) SMAX = SMax[v][0];
if(Max[u][0] > MAX){
SMAX = MAX;
MAX = Max[u][0];
}
else if(Max[u][0] != MAX && Max[u][0] > SMAX) SMAX = Max[u][0];
if(SMax[u][0] > SMAX) SMAX = SMax[u][0];
}
if(MAX == Ans) return SMAX;
else return MAX;
}
int main(){
Open("milk");
n = read(); m = read();
init();
for(int i = 1; i <= m; ++i){
s[i].from = read();
s[i].to = read();
s[i].dis = read();
}
sort(s + 1, s + m + 1);
int res = n - 1;
for(int i = 1; i <= m && res; ++i)
if(find(s[i].from) != find(s[i].to)){
merge(s[i].from, s[i].to);
ans += s[i].dis;
t[i] = 1;
Add(s[i].from, s[i].to, s[i].dis);
Add(s[i].to, s[i].from, s[i].dis);
}
DFS(s[1].from, 0);
for(int i = 1; i <= 21; ++i)
for(int j = 1; j <= n; ++j){
f[j][i] = f[f[j][i - 1]][i - 1];
Max[j][i] = max(Max[j][i - 1], Max[f[j][i - 1]][i - 1]);
if(Max[j][i - 1] != Max[f[j][i - 1]][i - 1])
SMax[j][i] = max(min(Max[j][i - 1], Max[f[j][i - 1]][i - 1]), max(SMax[j][i - 1], SMax[f[j][i - 1]][i - 1]));
else SMax[j][i] = max(SMax[j][i - 1], SMax[f[j][i - 1]][i - 1]);
}
int ANS = INF;
for(int i = 1; i <= m; ++i){
if(!t[i]){
ANS = min(ANS, s[i].dis - LCA(s[i].from, s[i].to, s[i].dis));
}
}
printf("%d\n", ans + ANS);
Close;
//system("pause");
return 0;
}

【洛谷 P4180】【模板】严格次小生成树[BJWC2010](倍增)的更多相关文章

  1. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  2. 【洛谷P4180】严格次小生成树

    题目大意:给定一个 N 个顶点,M 条边的带权无向图,求该无向图的一个严格次小生成树. 引理:有至少一个严格次小生成树,和最小生成树之间只有一条边的差异. 题解: 通过引理可以想到一个暴力,即:先求出 ...

  3. 洛谷P4180 [Beijing2010组队]次小生成树Tree

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

  4. P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 倍增(LCA)+最小生成树 施工队挖断学校光缆导致断网1天(大雾) 考虑直接枚举不在最小生成树上的边.但是边权可能与最小生成树上的边相等,这样删 ...

  5. 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)

    洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...

  6. 洛谷P4180【Beijing2010组队】次小生成树Tree

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

  7. 【洛谷】4180:【模板】严格次小生成树[BJWC2010]【链剖】【线段树维护最大、严格次大值】

    P4180 [模板]严格次小生成树[BJWC2010] 题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说, ...

  8. Luogu P4180 【模板】严格次小生成树[BJWC2010]

    P4180 [模板]严格次小生成树[BJWC2010] 题意 题目描述 小\(C\)最近学了很多最小生成树的算法,\(Prim\)算法.\(Kurskal\)算法.消圈算法等等.正当小\(C\)洋洋得 ...

  9. 「LuoguP4180」 【模板】严格次小生成树[BJWC2010](倍增 LCA Kruscal

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

  10. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

随机推荐

  1. ACM 第十一天

    多校7题目 GuGuFishtion Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  2. 选择正确的C/C++ runtime library

    本文是对http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html的翻译,如有错误,还请指正 c/c++运行库(ru ...

  3. CDN概念基本介绍

    CDN概念基本介绍 一 . CDN简介 什么是CDN? CDN的全称是Content Delivery Network,即内容分发网络. 其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的 ...

  4. SPD各模块总结

    一.用户角色绑定节点 1.库存操作员.库存主管.验货操作员:绑定任一节点 2.采购操作员.公药操作员:只能绑定药库节点 3.退库操作员.药品申领员:绑定药库以外的节点 二.采购计划模块 1.采购计划的 ...

  5. Android ListView的优化

    最近的项目中有通讯录这个模块,里面的通讯录涉及的联系人数量很大,导致在加载页面的时候有点卡,所以就必须得进行优化,优化的最终实现理论是什么?就是让ListView一次性加载的数据较少,后续根据用户操作 ...

  6. BZOJ2337:[HNOI2011]XOR和路径——题解

    +++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...

  7. LG. 1003 铺地毯

    LG. 1003 铺地毯 题意分析 给出平面中地毯的左上角坐标和长宽,然后给出一点(x,y).求此点最上面是哪个地毯的编号,若没被覆盖则输出-1. 将所有地毯的信息存在一个结构体中,由于后埔地毯在上面 ...

  8. bzoj1263: [SCOI2006]整数划分(高精度+构造)

    第一次写压位高精度只好抄黄学长的 代码最后一段想了好久一看评论区才知道黄学长写错了= =很气 自己最后改对了T^T 这题最优是一直划分3出来直到<=4 #include<iostream& ...

  9. 2016多校联合训练1 B题Chess (博弈论 SG函数)

    题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外 ...

  10. [BZOJ1131/POI2008]Sta树的深度

    Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output ...