次小生成树算法(严格LCA)
发布日期:2021-06-30 10:23:26
浏览次数:2
分类:技术文章
本文共 3739 字,大约阅读时间需要 12 分钟。
有定理
存在次小生成树,只替换最小生成树的一条边得来。
那么先跑一遍最小生成树
然后枚举不在树边的边 ( u , v ) (u,v) (u,v)
假如加入这条边,树就会成环,我们需要删掉 u − > v u->v u−>v的一条树边
显然删掉最大的那条边最优秀
这个过程使用 L C A LCA LCA来优化
带权 L C A LCA LCA
#includeusing namespace std;#define int long longconst int maxn=2e5+10; const int inf=1e18;int n,m;int pre[maxn],deep[maxn],lg[maxn],ok[maxn];int fa[maxn][21],maxx[maxn][21],ci[maxn][21];struct p{ int l,r,w; bool operator < (const p&tmp ){ return w maxx[r][i-1] ) ci[u][i] = max( ci[u][i],maxx[r][i-1] ); else if( maxx[u][i-1] =0;i--) if( deep[fa[x][i]]>=deep[y] ) { if( w!=maxx[x][i] ) ans = max(ans,maxx[x][i] ); else ans = max(ans,ci[x][i] ); x = fa[x][i]; } if( x==y ) return ans; for(int i=20;i>=0;i--) if( fa[x][i]!=fa[y][i] ) { if( w!=maxx[x][i] ) ans = max(ans,maxx[x][i] ); else ans = max(ans,ci[x][i] ); if( w!=maxx[y][i] ) ans = max(ans,maxx[y][i] ); else ans = max(ans,ci[y][i] ); x=fa[x][i],y=fa[y][i]; } if( w!=maxx[x][0] ) ans = max(ans,maxx[x][0] ); else ans = max(ans,ci[x][0] ); if( w!=maxx[y][0] ) ans = max(ans,maxx[y][0] ); else ans = max(ans,ci[y][0] ); return ans;}void init(){ for(int i=1;i<=n;i++) lg[i] = lg[i-1]+((1< > n >> m; init(); for(int i=1;i<=m;i++) cin >> a[i].l >> a[i].r >> a[i].w; int chu = kur(); ci[1][0]=-inf; dfs(1,0); int ans = inf; for(int i=1;i<=m;i++) { if( ok[i] ) continue; int u = a[i].l,v = a[i].r, w = a[i].w; ans = min( ans,chu-LCA(u,v,w)+w ); } cout << ans;}
先求 l c a lca lca再跳,其实都差不多
#includeusing namespace std;#define int long longconst int maxn=2e5+10; const int inf=1e18;int n,m;int pre[maxn],deep[maxn],lg[maxn],ok[maxn];int fa[maxn][21],maxx[maxn][21],ci[maxn][21];struct p{ int l,r,w; bool operator < (const p&tmp ){ return w maxx[r][i-1] ) ci[u][i] = max( ci[u][i],maxx[r][i-1] ); else if( maxx[u][i-1] =0;i--) if( deep[fa[x][i]]>=deep[y] ) x=fa[x][i]; if( x==y ) return x; for(int i=20;i>=0;i--) if( fa[x][i]!=fa[y][i] ) x=fa[x][i],y=fa[y][i]; return fa[x][0];}int make_max(int x,int y,int da){ int ans = -inf; for(int i=20;i>=0;i--) if( deep[fa[x][i]]>=deep[y] ) { if( da!=maxx[x][i] ) ans =max( ans,maxx[x][i] ); else ans = max( ans,ci[x][i] ); x = fa[x][i]; } return ans;}void init(){ for(int i=1;i<=n;i++) lg[i] = lg[i-1]+((1< > n >> m; init(); for(int i=1;i<=m;i++) cin >> a[i].l >> a[i].r >> a[i].w; int chu = kur(); ci[1][0]=-inf; dfs(1,0); int ans = inf; for(int i=1;i<=m;i++) { if( ok[i] ) continue; int u = a[i].l,v = a[i].r, w = a[i].w; int lca = LCA(u,v); int q=make_max(u,lca,w), e = make_max(v,lca,w); ans = min( ans,chu-max(q,e)+w ); } cout << ans;}
非严格次小生成树
#include#include #include #include using namespace std;const int maxn = 2e5+10;const int inf = 1e9;struct p{ int l,r,w; bool operator < (const p&tmp ) const{ return w =0;i--) if( deep[fa[x][i]]>=deep[y] ) { ans = max( ans,maxx[x][i] ); x = fa[x][i]; } if( x==y ) return ans; for(int i=20;i>=0;i--) if( fa[x][i]!=fa[y][i] ) { ans = max( ans,max(maxx[x][i],maxx[y][i]) ); x = fa[x][i], y = fa[y][i]; } ans = max( ans,max( maxx[x][0],maxx[y][0]) ); return ans;}void init(){ for(int i=1;i<=m;i++) ok[i] = 0; cnt = 1; for(int i=1;i<=n;i++) head[i] = 0;}int main(){ int T; cin >> T; while( T-- ) { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) cin >> a[i].l >> a[i].r >> a[i].w; int chu = kur(),ans = inf; dfs(1,0); for(int i=1;i<=m;i++) { if( ok[i] ) continue; ans = min( ans , chu-lca(a[i].l,a[i].r)+a[i].w ); }// if( chu==ans ) cout << "Not Unique!\n";// else cout << chu << endl; init(); }}
转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/109382370 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年04月20日 18时35分08秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
JAVA学习笔记3 - 运算符
2019-04-30
JAVA学习笔记4 - 循环与分支结构
2019-04-30
JAVA学习笔记6 - 数组
2019-04-30
JAVA学习笔记8 - Stream 和 File I/O
2019-04-30
JAVA学习笔记9 - 异常
2019-04-30
JAVA学习笔记10 - 继承
2019-04-30
JAVA学习笔记11 - 接口interface
2019-04-30
JAVA学习笔记12 - 包package
2019-04-30
Android 开发学习笔记 00 - Getting Started
2019-04-30
【学习笔记】Android Activity
2019-04-30
【学习笔记】Android Fragments
2019-04-30
Android使用Retrofit_00_Getting Started
2019-04-30
Android使用Retrofit_01_OAuth2 + GitHub
2019-04-30
Django + REST学习笔记
2019-04-30
【转载】将Ubuntu16.04 中gedit在仅显示一个文件时显示文件名tab
2019-04-30