bzoj1977 [BeiJing2010组队]次小生成树 Tree——严格次小生成树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1977
因为严格,所以要记录到 LCA 的一个次小值;
很快写好,然后改掉一堆错误后终于过了样例!然而交上去1WA;
又改了半天,还是WA,于是放弃,抄题解好久...
然而就在我调了一个小时终于锁定错误就在那个子函数里的时候才突然看到了自己的明显惊天大错误是怎么回事??!!!稍微改了一下下就完美AC。。。
不过还有点收获,把求各种层次的 f 放在 dfs 函数里会比单独拿出来再求一遍快 1000+ms 哦~
题解的写法是直接看 u 到 lca 和 v 到 lca 路上的值,而我是求 lca 的过程中求值的,还是喜欢我的写法;
题解的写法放在注释里了;
囧。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e5+,maxm=3e5+,inf=1e9;
int n,m,f[maxn][],dep[maxn],mx[maxn][],nmx[maxn][];//
int hd[maxn],ct,fa[maxn],d[maxn],mnn;
ll ans;//ll
bool vis[maxn],used[maxm];
struct P{int u,v,w;}e[maxm];
struct T{
int mx,nmx;
T(int x=,int n=):mx(x),nmx(n) {}
};
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxn<<];
bool cmp(P x,P y){return x.w<y.w;}
void add(int x,int y,int w){ed[++ct]=N(y,hd[x],w); hd[x]=ct;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int x)
{
for (int i=; i<=; i++)//写在这里较快
{
if(dep[x]<(<<i))break;
f[x][i]=f[f[x][i-]][i-];
mx[x][i]=max(mx[x][i-],mx[f[x][i-]][i-]);
if (mx[x][i-]==mx[f[x][i-]][i-])
nmx[x][i]=max(nmx[x][i-],nmx[f[x][i-]][i-]);
else
nmx[x][i]=min(mx[x][i-],mx[f[x][i-]][i-]),
nmx[x][i]=max(nmx[x][i],nmx[x][i-]),
nmx[x][i]=max(nmx[x][i],nmx[f[x][i-]][i-]);
}
vis[x]=;
for(int i=hd[x],u;i;i=ed[i].nxt)
if(!vis[u=ed[i].to])
{
f[u][]=x; dep[u]=dep[x]+;
mx[u][]=ed[i].w;
// nmx[u][0]=ed[i].w;//无!
d[u]=ed[i].w;
dfs(u);
}
}
void init()
{
dep[]=; dfs();
// for(int j=1;j<=20;j++)
// for(int i=1;i<=n;i++)
// {
// int tmx=mx[f[i][j-1]][j-1],tnx=nmx[f[i][j-1]][j-1];
// f[i][j]=f[f[i][j-1]][j-1];
// mx[i][j]=max(mx[i][j-1],tmx);
// if(tmx>mx[i][j-1]) nmx[i][j]=max(mx[i][j-1],tnx);
// else if(tmx==mx[i][j-1]) nmx[i][j]=max(nmx[i][j-1],tnx);
// else nmx[i][j]=max(nmx[i][j-1],tmx);
// }
}
void ch(int &rmx,int &rnx,int tmx,int tnx)
{
if(tmx>rmx)
{
rnx=max(tnx,rmx);
rmx=tmx;
}
else if(tmx==rmx) rnx=max(tnx,rnx);
else rnx=max(rnx,tmx);
}
T lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int k=dep[x]-dep[y],rmx=-,rnx=-;
for(int i=;i>=;i--)
// if((1<<i)&k){rmx=mx[x][i]; rnx=nmx[x][i]; x=f[x][i];}//x放在后面修改!
if((<<i)&k){ch(rmx,rnx,mx[x][i],nmx[x][i]); x=f[x][i];}//!!!!!!囧
for(int i=;i>=;i--)
if(f[x][i]!=f[y][i])
{
ch(rmx,rnx,mx[x][i],nmx[x][i]);
ch(rmx,rnx,mx[y][i],nmx[y][i]);
x=f[x][i]; y=f[y][i]; //后面改!!
}
if(x!=y) ch(rmx,rnx,max(d[x],d[y]),min(d[x],d[y]));
return T(rmx,rnx);
}
//int LCA(int x,int y)
//{
// if(dep[x]<dep[y])swap(x,y);
// int k=dep[x]-dep[y];
// for(int i=20;i>=0;i--)
// if((1<<i)&k){rmx=mx[x][i]; rnx=nmx[x][i]; x=f[x][i];}
// for(int i=20;i>=0;i--)
// if(f[x][i]!=f[y][i])
// {
// x=f[x][i]; y=f[y][i];
// }
// if(x==y)return x;
// return f[x][0];
//}
//T work(int x,int lca)
//{
// T ret;
// int maxx1=-1,maxx2=-1;
// int d=dep[x]-dep[lca];
// for (int i=0; i<=20; i++)
// if (d&(1<<i))
// {
// ch(maxx1,maxx2,mx[x][i],nmx[x][i]);
// x=f[x][i];
// }
// ret.mx=maxx1,ret.nmx=maxx2;
// return ret;
//}
//T solve(int x)
//{
// T ret;
// int u=e[x].u,v=e[x].v,lca=LCA(u,v);
// T uu=work(u,lca);
// T vv=work(v,lca);
// ret.mx=max(uu.mx,vv.mx);
// if(uu.mx>vv.mx) ret.nmx=max(vv.mx,uu.nmx);
// else if(uu.mx==vv.mx) ret.nmx=max(vv.nmx,uu.nmx);
// else ret.nmx=max(uu.mx,vv.nmx);
// return ret;
//}
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);
sort(e+,e+m+,cmp);
for(int i=;i<=n;i++)fa[i]=i;
int cnt=;
for(int i=,u,v;i<=m;i++)
if(find(u=e[i].u)!=find(v=e[i].v))
{
cnt++;
fa[find(u)]=find(v);
used[i]=; ans+=e[i].w;
add(u,v,e[i].w); add(v,u,e[i].w);
if(cnt==n-)break;
}
init();
mnn=inf;
for(int i=;i<=m;i++)
{
if(used[i])continue;
int u=e[i].u,v=e[i].v;
T l=lca(u,v);
// T l=solve(i);
if(e[i].w==l.mx)mnn=min(mnn,e[i].w-l.nmx);
else mnn=min(mnn,e[i].w-l.mx);
}
printf("%lld",ans+mnn);
return ;
}
bzoj1977 [BeiJing2010组队]次小生成树 Tree——严格次小生成树的更多相关文章
- 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- [bzoj1977][BeiJing2010组队]次小生成树 Tree——树上倍增+lca
Brief Description 求一个无向图的严格次小生成树. Algorithm Design 考察最小生成树的生成过程.对于一个非树边而言,如果我们使用这一条非树边去替换原MST的路径上的最大 ...
- bzoj1977 [BeiJing2010组队]次小生成树 Tree
和倍增法求lca差不多,维护每个点往上跳2^i步能到达的点,以及之间的边的最大值和次大值,先求出最小生成树,对于每个非树边枚举其端点在树上的路径的最大值,如果最大值和非树边权值一样则找次大值,然后维护 ...
- [BZOJ1977][BeiJing2010组队]次小生成树
题解: 首先要证明一个东西 没有重边的图上 次小生成树由任何一颗最小生成树替换一条边 但是我不会证啊啊啊啊啊啊啊 然后就很简单了 枚举每一条边看看能不能变 但有一个特殊情况就是,他和环上的最大值相等, ...
- 2018.09.15 bzoj1977:次小生成树 Tree(次小生成树+树剖)
传送门 一道比较综合的好题. 由于是求严格的次小生成树. 我们需要维护一条路径上的最小值和次小值. 其中最小值和次小值不能相同. 由于不喜欢倍增我选择了用树链剖分维护. 代码: #include< ...
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
[BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...
- 1977: [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...
- [BeiJing2010组队]次小生成树 Tree
1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 5168 Solved: 1668[S ...
随机推荐
- 使用cloudcompare进行对比轨迹及评价
0.预备知识: 我的系统是Ubuntu 16.04. 在其他发行版中,可能需要先安装snap(如有必要,请参阅相应的文档).快照发布在3个频道:“稳定”,“测试版”和“边缘”.“稳定版”和“测试版”频 ...
- 17Aspectij
17Aspectij-2018/07/31 1.Aspectj基于xml 前置通知 method : 通知,及方法名 pointcut :切入点表达式,此表达式只能当前通知使用. pointcut-r ...
- java解析从接口获取的json内容并写到excle(只写与标题匹配的值,并非把所有的接口返回值都写进去)
需求:从接口中获取的一个json数组中有多个对象,每个对象中的值并非都需要,只需查出标题中的几项对应的值即可.且还需要按某个字段排序后依次写到excel 实现方法如下: package jansonD ...
- Linux学习笔记(六) 进程管理
1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...
- 版本优化-test
版本优化 标签(空格分隔): 测试 需求经手人太多,直接提bug,开发不乐意,跟Leader确认不靠谱,跟PM确认,不熟悉流程,跟第三方PM确认靠谱了,结果被开发三言两语,变成了不改bug 而改需求 ...
- The Falling Leaves(建树方法)
uva 699 紫书P159 Each year, fall in the North Central region is accompanied by the brilliant colors of ...
- Python基础之生成器、迭代器
一.字符串格式化进阶 Python的字符串格式化有两种方式: 百分号方式.format方式,由于百分号的方式相对来说比较老,在社区里讨论format方式有望取代百分号方式,下面我们分别介绍一下这两种方 ...
- 【19】AngularJS 应用
AngularJS 应用 现在是时候创建一个真正的 AngularJS 单页 Web 应用(single page web application,SPA)了. AngularJS 应用实例 现在可以 ...
- 【Codeforces 598D】Igor In the Museum
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 同一个联通块里面答案都一样. 把每个联通块的答案都算出来 然后赋值就好 [代码] #include <bits/stdc++.h> ...
- java 生成20位唯一ID,生成不会重复的20位数字----https://blog.csdn.net/weixin_36751895/article/details/70331781
java 生成20位唯一ID,生成不会重复的20位数字----https://blog.csdn.net/weixin_36751895/article/details/70331781