【Beijing 2010】 次小生成树
【题目链接】
【算法】
首先,有一个结论 : 一定有一棵严格次小生成树是在最小生成树的基础上去掉一条边,再加上一条边
这个结论的正确性是显然的
我们先用kruskal算法求出最小生成树,然后,枚举不在最小生成树上的边,我们发现若加上这条边,
则形成了一个环,用最小生成树的权值和加上这条边的权值再减去在这个环上且在最小生成树上权值
最大的边即为包括这条边的最小生成树的权值和
那么,树上倍增可以解决这个问题
因为是要求严格最小,所以我们不仅要记录最大值,还要记录次大值
时间复杂度 : O((N+M)log(N))
【代码】
注意使用long long,INF开到10^18!
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define MAXM 300010
#define MAXLOG 20
const long long INF = 1e18; struct info
{
int x,y;
long long w;
} edge[MAXM];
struct Edge
{
int to;
long long w;
int nxt;
} e[MAXM<<]; int i,n,m,tot;
int fa[MAXN],head[MAXN],dep[MAXN],anc[MAXN][MAXLOG];
long long ans = INF,val;
long long mx[MAXN][MAXLOG],nx[MAXN][MAXLOG];
bool on_mst[MAXM]; inline bool cmp(info a,info b) { return a.w < b.w; }
inline int get_root(int x)
{
if (fa[x] == x) return x;
return fa[x] = get_root(fa[x]);
}
inline void add(int x,int y,int w)
{
tot++;
e[tot] = (Edge){y,w,head[x]};
head[x] = tot;
}
inline void kruskal()
{
int i,sx,sy;
long long x,y,w;
for (i = ; i <= n; i++) fa[i] = i;
for (i = ; i <= m; i++) on_mst[i] = false;
sort(edge+,edge+m+,cmp);
for (i = ; i <= m; i++)
{
x = edge[i].x;
y = edge[i].y;
w = edge[i].w;
sx = get_root(x);
sy = get_root(y);
if (sx != sy)
{
val += w;
fa[sx] = sy;
on_mst[i] = true;
add(x,y,w);
add(y,x,w);
}
}
}
inline void dfs_init(int u)
{
int i,v;
for (i = ; i < MAXLOG; i++)
{
if (dep[u] < ( << i)) break;
anc[u][i] = anc[anc[u][i-]][i-];
mx[u][i] = max(mx[u][i-],mx[anc[u][i-]][i-]);
if (mx[u][i-] == mx[anc[u][i-]][i-]) nx[u][i] = max(nx[u][i-],nx[anc[u][i-]][i-]);
else nx[u][i] = max(min(mx[u][i-],mx[anc[u][i-]][i-]),max(nx[u][i-],nx[anc[u][i-]][i-]));
}
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
if (anc[u][] != v)
{
dep[v] = dep[u] + ;
anc[v][] = u;
mx[v][] = e[i].w;
dfs_init(v);
}
}
}
inline long long get(int x,int y,long long w)
{
int i,t;
long long ret = ;
if (dep[x] > dep[y]) swap(x,y);
t = dep[y] - dep[x];
for (i = ; i < MAXLOG; i++)
{
if (t & ( << i))
{
if (mx[y][i] == w) ret = max(ret,nx[y][i]);
else ret = max(ret,mx[y][i]);
y = anc[y][i];
}
}
if (x == y) return ret;
for (i = MAXLOG - ; i >= ; i--)
{
if (anc[x][i] != anc[y][i])
{
if (mx[x][i] == w) ret = max(ret,nx[x][i]);
else ret = max(ret,mx[x][i]);
if (mx[y][i] == w) ret = max(ret,nx[y][i]);
else ret = max(ret,mx[y][i]);
x = anc[x][i];
y = anc[y][i];
}
}
if (mx[x][] != w) ret = max(ret,mx[x][]);
if (mx[y][] != w) ret = max(ret,mx[y][]);
return ret;
}
int main()
{ scanf("%d%d",&n,&m);
for (i = ; i <= m; i++) scanf("%lld%lld%lld",&edge[i].x,&edge[i].y,&edge[i].w);
kruskal();
dfs_init();
for (i = ; i <= m; i++)
{
if (!on_mst[i])
ans = min(ans,val+edge[i].w-get(edge[i].x,edge[i].y,edge[i].w));
}
printf("%lld\n",ans); return ;
}
【Beijing 2010】 次小生成树的更多相关文章
- [BJOI 2010]次小生成树Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- [Luogu P4180][BJWC 2010]严格次小生成树
严格次小生成树,关键是“严格”,如果是不严格的其实只需要枚举每条不在最小生成树的边,如果得到边权和大于等于最小生成树的结束就行.原理就是因为Kruskal非常贪心,只要随便改一条边就能得到一个非严格的 ...
- 次小生成树(lca)
题目描述 原题来自:BeiJing 2010 组队赛 给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树. 设最小生成树的边权之和为 sum,严格次小生成树就是指边权之和大于 sum 的生 ...
- hdu 4081 Qin Shi Huang's National Road System (次小生成树)
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- HDU4081 Qin Shi Huang's National Road System —— 次小生成树变形
题目链接:https://vjudge.net/problem/HDU-4081 Qin Shi Huang's National Road System Time Limit: 2000/1000 ...
- HDU-4081.Qinshihuang'sNationalRoadSystem(次小生成树变种)
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- HDU 4081Qin Shi Huang's National Road System(次小生成树)
题目大意: 有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点.秦始皇希望这所有n-1条路长度之和最短.然后徐福突然有冒出来,说是他有魔法,可以不用人力.财力就变 ...
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- The Unique MST(次小生成树)
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22335 Accepted: 7922 Description Give ...
随机推荐
- [Python3网络爬虫开发实战] 1.5.1-PyMySQL的安装
在Python 3中,如果想要将数据存储到MySQL中,就需要借助PyMySQL来操作,本节中我们介绍一下它的安装方式. 1. 相关链接 GitHub:https://github.com/PyMyS ...
- JavaScript在HTML中的应用
JavaScript在HTML中的应用 制作人:全心全意 在HTML文档中可以使用<script>...</script>标记将JavaScript脚本嵌入到其中,在HTML文 ...
- 第二十三节:scrapy爬虫识别验证码(二)图片验证码识别
图片验证码基本上是有数字和字母或者数字或者字母组成的字符串,然后通过一些干扰线的绘制而形成图片验证码. 例如:知网的注册就有图片验证码 首先我们需要获取验证码图片,通过开发者工具我们可以得到验证码ur ...
- (贪心) Vacations 求休息的最少天数
Description Vasya has n days of vacations! So he decided to improve his IT skills and do sport. Vasy ...
- allegro中查看寄生参数
在allegro中可以查看线的寄生参数,这个命令所在的位置在如下如位置: 版权声明:本文为博主原创文章,未经博主允许不得转载.
- centos7安装mysql5.7.19及配置远程连接
centos7安装mysql5.7.19及配置远程连接------https://blog.csdn.net/Lh19931122/article/details/77996213
- HTML5学习之语义化标签
一.为什么HTML5要引入新语义标签 在HTML5出现之前,我们一般采用DIV+CSS布局我们的页面.但是这样的布局方式不仅使我们的文档结构不够清晰,而且不利于搜索引擎爬虫对我们页面的爬取.为了解决上 ...
- SOJ 2818_QQ音速
[题意]两只手,一次只能用一只手按一个键子(0,1,2,3),给出从i键到j键所需的消耗的体力,求依次按下一系列键子所需最小体力. [分析] 法一:开一个三维数组,分别记录移动到位置及左右手按的键子. ...
- Servlet开发(3)
Servlet开发 Servlet过滤器: 主要是对访问主页的用户进行过滤,通过登录系统进入的用户可以看到主页内容,在session中存在currentuser. 可以对此进行判断: package ...
- JSP的体系结构
以下内容引用自http://wiki.jikexueyuan.com/project/jsp/architecture.html: Web服务器需要一个JSP引擎,即处理JSP页面的容器.JSP容器负 ...