[BJOI2010]次小生成树
OJ题号:
BZOJ1977、COGS2453
题目大意:
给你一个无向连通图,求严格次小生成树。
思路:
对于一般次小生成树,我们有一个结论:一般次小生成树一定可以通过替换掉最小生成树某一条边得到。
因此对于一般次小生成树,我们只需要枚举不在MST上的每一条边,并枚举这条边对应两点路径上的所有边,尝试交换这两条边即可。
显然枚举树上每一条边的复杂度是O(n)的,会TLE,因此我们可以用树剖或者树上倍增的方法记录区间最大边。
然而这题要求的是严格次小生成树,所以万一你枚举的这两条边相等就WA了。
为了保险起见,我们再记录区间最大边的同时,还要记录区间严格次大边。
然后枚举的时候只要判断当前区间最大边是否和那条非树边相等,如果相等的话就取那条次大边即可。
一开始因为没有权限号就去COGS上交,然后随随便便就A了,还跑了Rank1。
但是据说那里数据比较水,就找q234rty借了权限号,去BZOJ上交,果然WA了。
随机了一个小数据,发现是最后倍增求最大树边的时候最后一层没跳上去。
去网上拉了一个程序对拍,发现无限WA。
拿了一个数据手动模拟了一遍,发现原来是网上的题解错了。。
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const long long inf=0x7fffffffffffffffll;
const int V=,logV=;
inline int log2(const float x) {
return ((unsigned&)x>>&)-;
}
class DisjointSet {
private:
int anc[V];
int Find(const int &x) {
return x==anc[x]?x:anc[x]=Find(anc[x]);
}
public:
DisjointSet() {
for(register int i=;i<V;i++) {
anc[i]=i;
}
}
void Union(const int &x,const int &y) {
anc[Find(x)]=Find(y);
}
bool isConnected(const int &x,const int &y) {
return Find(x)==Find(y);
}
};
DisjointSet s;
struct Edge1 {
int u,v,w;
bool inMST;
bool operator < (const Edge1 &another) const {
return w<another.w;
}
};
std::vector<Edge1> e1;
struct Edge {
int to,w;
};
std::vector<Edge> e[V];
inline void add_edge(const int &u,const int &v,const int &w) {
e[u].push_back((Edge){v,w});
}
long long mst=;
inline void kruskal() {
std::sort(e1.begin(),e1.end());
for(register unsigned i=;i<e1.size();i++) {
const int &u=e1[i].u,&v=e1[i].v,&w=e1[i].w;
if(s.isConnected(u,v)) continue;
s.Union(u,v);
add_edge(u,v,w);
add_edge(v,u,w);
e1[i].inMST=true;
mst+=w;
}
}
int anc[V][logV],max[V][logV],max2[V][logV];
int dep[V];
std::queue<int> q;
inline void bfs() {
q.push();
while(!q.empty()) {
const int x=q.front();
q.pop();
dep[x]=dep[anc[x][]]+;
for(register int i=;i<=log2(dep[x]);i++) {
anc[x][i]=anc[anc[x][i-]][i-];
max[x][i]=std::max(max[x][i-],max[anc[x][i-]][i-]);
if(max[x][i-]!=max[anc[x][i-]][i-]) {
max2[x][i]=std::min(max[x][i-],max[anc[x][i-]][i-]);
} else {
max2[x][i]=std::max(max2[x][i-],max2[anc[x][i-]][i-]);
}
}
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(y==anc[x][]) continue;
anc[y][]=x;
max[y][]=e[x][i].w;
q.push(y);
}
}
}
inline int maxEdge(int x,int y,const int &w) {
int tmax=;
while(dep[x]!=dep[y]) {
if(dep[x]<dep[y]) std::swap(x,y);
for(register int i=log2(dep[x]);i>=;i--) {
if(dep[anc[x][i]]>=dep[y]) {
if(max[x][i]<w) {
tmax=std::max(tmax,max[x][i]);
} else if(max2[x][i]<w) {
tmax=std::max(tmax,max2[x][i]);
}
x=anc[x][i];
}
}
}
if(x==y) return tmax;
for(register int i=log2(dep[x]);i>=;i--) {
if(anc[x][i]!=anc[y][i]) {
if(max[x][i]<w) {
tmax=std::max(tmax,max[x][i]);
} else if(max2[x][i]<w) {
tmax=std::max(tmax,max2[x][i]);
}
if(max[y][i]<w) {
tmax=std::max(tmax,max[y][i]);
} else if(max2[y][i]<w) {
tmax=std::max(tmax,max2[y][i]);
}
x=anc[x][i],y=anc[y][i];
}
}
if(max[x][]<w) {
tmax=std::max(tmax,max[x][]);
} else if(max2[x][]<w) {
tmax=std::max(tmax,max2[x][]);
}
if(max[y][]<w) {
tmax=std::max(tmax,max[y][]);
} else if(max2[y][]<w) {
tmax=std::max(tmax,max2[y][]);
}
return tmax;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("secmst.in","r+",stdin);
freopen("secmst.out","w+",stdout);
#endif
int n=getint(),m=getint();
for(register int i=;i<=m;i++) {
const int u=getint(),v=getint(),w=getint();
e1.push_back((Edge1){u,v,w,false});
}
kruskal();
bfs();
long long ans=inf;
for(register unsigned i=;i<e1.size();i++) {
if(e1[i].inMST) continue;
const int &u=e1[i].u,&v=e1[i].v,&w=e1[i].w;
ans=std::min(ans,mst-maxEdge(u,v,w)+w);
}
printf("%lld\n",ans);
#ifndef ONLINE_JUDGE
fclose(stdin),fclose(stdout);
#endif
return ;
}
[BJOI2010]次小生成树的更多相关文章
- [BJOI2010] 严格次小生成树
题目链接 一个严格次小生成树的模板题. 看到次小生成树,我们有一个很直观的想法就是先构造出来最小生成树,然后将这个最小生成树上面最大的一条边替换成和它值最相近而且比他大的边. 那么首先就是用krusk ...
- 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 ...
- URAL 1416 Confidential --最小生成树与次小生成树
题意:求一幅无向图的最小生成树与最小生成树,不存在输出-1 解法:用Kruskal求最小生成树,标记用过的边.求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就 ...
- POJ1679The Unique MST(次小生成树)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 25203 Accepted: 8995 D ...
- [kuangbin带你飞]专题八 生成树 - 次小生成树部分
百度了好多自学到了次小生成树 理解后其实也很简单 求最小生成树的办法目前遇到了两种 1 prim 记录下两点之间连线中的最长段 F[i][k] 之后枚举两点 若两点之间存在没有在最小生成树中的边 那么 ...
- URAL 1416 Confidential(次小生成树)
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1416 Zaphod Beeblebrox — President of the Impe ...
- ACM题目————次小生成树
Description 最小生成树大家都已经很了解,次小生成树就是图中构成的树的权值和第二小的树,此值也可能等于最小生成树的权值和,你的任务就是设计一个算法计算图的最小生成树. Input 存在多组数 ...
随机推荐
- python学习笔记之split()方法与with
Python split()方法 以下内容摘自:http://www.runoob.com/python/att-string-split.html 描述 Python split()通过指定分隔符对 ...
- aarch64_l1
L-function-1.23-18.fc26.aarch64.rpm 2017-02-14 08:01 139K fedora Mirroring Project L-function-devel- ...
- avalonJS-源码阅读(二)
上一篇文章讲述的avalon刷页面所用到的几个函数.这篇则是主要讲avalon对刷DOM刷出来的avalon自定义属性如何处理的. 目录[-] avalon页面处理(2) 数据结构 解析avalon标 ...
- java使用DOM操作XML
XML DOM简介 XML DOM 是用于获取.更改.添加或删除 XML 元素的标准. XML 文档中的每个成分都是一个节点. DOM 是这样规定的: 整个文档是一个文档节点 每个 XML 标签是一个 ...
- python基础--hashlib模块
hashlib模块用于加密操作,代替了md5和sha模块, 主要提供SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法. # -*- coding:utf-8 - ...
- PV操作2011
- H5新特性:video与audio的使用
HTML5 DOM 为 <audio> 和 <video> 元素提供了方法.属性和事件. 这些方法.属性和事件允许您使用 JavaScript 来操作 <audio> ...
- 高版本SQL备份在低版本SQL还原问题
问题描述: 高版本SQL备份在低版本SQL还原问题(出现媒体簇的结构不正确) 分析原因: SQL版本兼容问题,SQL SERVER兼容级别是用作向下兼容用,高版本的SQL备份在低版本中不兼容 ...
- Oracle学习笔记:ORA-22992 cannot use LOB locators selected from remote tables
通过DB_LINK访问远程表的时候出现 ORA-22992: cannot use LOB locators selected from remote tables 错误. 原因:因为表中含有clob ...
- CVE-2013-1347Microsoft Internet Explorer 8 远程执行代码漏洞
[CNNVD]Microsoft Internet Explorer 8 远程执行代码漏洞(CNNVD-201305-092) Microsoft Internet Explorer是美国微软(Mic ...