bzoj 1977 洛谷P4180 严格次小生成树
Description:
给定一张N个节点M条边的无向图,求该图的严格次小生成树。设最小生成树边权之和为sum,那么严格次小生成树就是边权之和大于sum的最小的一个
Input:
第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。
Output:
包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)
思路:先求出原图的最小生成树,然后继续从小到大枚举边(x,y),对于x,y用倍增求LCA的同时用一个ST表维护两点间的最大值,取最小的差值即可
书上好像用的是倍增LCA的同时用两个dp维护最大值和次大值,表示并看不怎么懂……
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + ;
#define ll long long int head[N], now;
struct edges{
int u, to, next, w;
}edge[N<<];
void add(int u, int v, int w){ edge[++now] = {u, v, head[u], w}; head[u] = now;} struct input{
int u, v, w;
}E[N];
int n, m, father[N], fa[N][];
ll mx[N][], d[N], tot;
bool vis[N]; int get(int x){
if(x != father[x]) return father[x] = get(father[x]);
return x;
}
bool cmp(input x, input y){ return x.w < y.w; }
void kruskal(){
sort(E + , E + m + , cmp);
for(int i = ; i <= n; i++) father[i] = i;
for(int i = ; i <= m; i++){
int x = get(E[i].u), y = get(E[i].v);
if(x != y) father[y] = x, tot += E[i].w, add(E[i].u, E[i].v, E[i].w), add(E[i].v, E[i].u, E[i].w), vis[i] = ;
}
}
void dfs(int x,int pre, int deep){
fa[x][] = pre; d[x] = deep;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(v == pre) continue;
mx[v][] = edge[i].w;
dfs(v, x, deep + );
}
}
void work(){
for(int j = ; j <= ; j++)
for(int i = ; i <= n; i++){
fa[i][j] = fa[fa[i][j - ]][j - ];
mx[i][j] = max(mx[i][j - ], mx[fa[i][j - ]][j - ]);
} }
ll getmax(int x,int y, int z){
if(y == -) return ;
if(mx[x][y] == z) return max(getmax(x, y - , z), getmax(fa[x][y - ], y - , z));
return mx[x][y];
}
ll query(int x, int y, int z){
ll maxn = ;
if(d[x] < d[y]) swap(x, y);
if(d[x] ^ d[y])
for(int i = ; i >= ; i--)
if(d[fa[x][i]] >= d[y]) maxn = max(maxn, getmax(x, i, z)), x = fa[x][i];
if(x == y) return z - maxn;
for(int i = ; i >= ; i--){
if(fa[x][i] != fa[y][i]){
maxn = max(maxn, max(getmax(x, i, z), getmax(y, i, z)));
x = fa[x][i], y = fa[y][i];
}
}
return z - max(maxn, max(getmax(x, , z), getmax(y, , z)));
}
int main(){
scanf("%d%d", &n, &m);
for(int i = ; i <= m; i++)
scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
kruskal();
dfs(, , );
work();
ll ans = 1e18;
for(int i = ; i <= m; i++)
if(!vis[i]){
ll tmp = query(E[i].u, E[i].v, E[i].w);
if(tmp) ans = min(ans, tot + tmp);
}
printf("%lld\n", ans);
return ;
}
bzoj 1977 洛谷P4180 严格次小生成树的更多相关文章
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- BZOJ1977或洛谷4180 [BJWC2010]次小生成树
一道LCA+生成树 BZOJ原题链接 洛谷原题链接 细节挺多,我调了半天..累炸.. 回到正题,我们先求出随便一棵最小生成树(设边权和为\(s\)),然后扫描剩下所有边,设扫到的边的两端点为\(x,y ...
- 洛咕P4180 严格次小生成树
鸽了很久的一道题(?)貌似是去年NOIP前听的emm... 首先我们分析一下最小生成树的性质 我们kruskal建树的时候呢是从小到大贪心加的边,这个的证明用到拟阵.(我太菜了不会) 首先我们不存在连 ...
- 洛谷 P 4180 次小生成树
题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得 ...
- 洛谷.4180.[模板]次小生成树Tree(Kruskal LCA 倍增)
题目链接 构建完MST后,枚举非树边(u,v,w),在树上u->v的路径中找一条权值最大的边(权为maxn),替换掉它 这样在 w=maxn 时显然不能满足严格次小.但是这个w可以替换掉树上严格 ...
- 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)
洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...
- 洛谷P4180【Beijing2010组队】次小生成树Tree
题目描述: 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还 ...
- [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)
[BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
随机推荐
- python网络编程,通过服务名称和会话类型(tcp,udp)获取端口号,简单的异常处理
作为一个php程序员,同时有对网络方面感兴趣,php就比较蛋疼了,所以就抽了些时间看python 之前学python基础因为工作原因,断断续续的看了个基础,差不多是可以写代码了 最近在看<pyt ...
- Ubuntu设置代理服务器
由于公司网络的原因,apache的网站访问不了,对于需要经常访问apache网站查看文档的我,最近想了一种方法,在自己的阿里云服务器上搭建一个代理服务器.经过查资料,最终决定使用TinyProxy. ...
- 如何防御网站被ddos攻击 首先要了解什么是流量攻击
什么是DDOS流量攻击?我们大多数人第一眼看到这个DDOS就觉得是英文的,有点难度,毕竟是国外的,其实简单通俗来讲,DDOS攻击是利用带宽的流量来攻击服务器以及网站. 举个例子,服务器目前带宽是100 ...
- sort()的部分用法
#include <iostream> #include <cstdio> #include <algorithm>//sort要包含的头文件 #include & ...
- 最小生成树算法 1.Prim算法
最小生成树(MST):一个有N个点的图,边一定是大于等于N-1条边的.在这些边中选择N-1条出来,连接所有N个点.这N-1条边的边权之和是所有方案中最小的. Prim算法的时间复杂度时O(n^2)的, ...
- 【EXCEL】SUMIF(条件を指定して数値を合計する)
Mirocrosoft Excel
- 【HNOI2008】玩具装箱TOY & 斜率优化学习笔记
题目 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为 \(1\cdots N\ ...
- Android4.0系统以上程序不出现菜单键的问题解决
去掉targetSdkVersion 或改为targetSdkVersion =13或更小.. 不改targetSdkVersion的办法:在onCreate() 里setContentView()之 ...
- 「日常训练」Soldier and Badges (CFR304D2B)
题意 (Codeforces 546B) 问对一个序列最少需要增减几个1能使其彼此不同. 分析 模拟处理.需要注意的是,尽管题目中说了an<=3000,问题是,如果一群a全是3000呢(滑稽), ...
- Htmlemail邮件发送
/** * * @param path //发送附件路径 * @param name //附件名称 * @param hostName //邮件服务器名称 * @param port //服务器端口 ...