bzoj1977: [BeiJing2010]次小生成树 kruskal+倍增LCA
来源:互联网 发布:json数组转换java对象 编辑:程序博客网 时间:2024/06/06 20:24
给定一张无向图,求严格次小的生成树(保证存在)
非严格次小的很好做
kruskal求出最小生成树,倍增求LCA与区间最大边权
枚举剩下的边两端点之间的最大值比较即可.
但是要严格次小的话,要在倍增时维护一个次大边权值
枚举时如果当前边与最大相等则比较次大
做的时候一堆奇怪的bug。。
#include <bits/stdc++.h>#define LL long longusing namespace std;const int N=100004,M=300005;struct Edge{int u,v,nex,flag;LL w;}e[M*2],edge[M*2];int n,m,tot,head[N],fa[N][20],dep[N],pa[N];LL ma[N][20],m2[N][20],sum;inline void Addedge(int u,int v,LL w){edge[++tot].v=v;edge[tot].nex=head[u];edge[tot].w=w;head[u]=tot;}bool cmp(const Edge &a,const Edge &b){return a.w<b.w;}int find(int v){if(pa[v]==v)return v;return pa[v]=find(pa[v]);}void kruskal(){int cnt=0;sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++)pa[i]=i;for(int i=1;i<=m;i++){if(cnt==n-1)break;int x=find(e[i].u),y=find(e[i].v);if(x!=y){pa[x]=y;sum+=e[i].w;cnt++;Addedge(e[i].u,e[i].v,e[i].w);Addedge(e[i].v,e[i].u,e[i].w);e[i].flag=1;//e[i].nex=head[e[i].u];head[e[i].u]=i;}}}void dfs(int u,int f){for(int i=1;i<=19;i++){int ff=fa[u][i-1];fa[u][i]=fa[ff][i-1];ma[u][i]=max(ma[u][i-1],ma[ff][i-1]);//m2[u][i]=getsec(ma[u][i-1],m2[u][i-1],ma[ff][i-1],m2[ff][i-1]);m2[u][i]=max(m2[u][i-1],m2[ff][i-1]);if(ma[u][i-1]!=ma[ff][i-1]) m2[u][i]=max(m2[u][i],min(ma[u][i-1],ma[ff][i-1]));}for(int i=head[u];i;i=edge[i].nex){int v=edge[i].v,w=edge[i].w;if(v==f)continue;fa[v][0]=u;ma[v][0]=w;dep[v]=dep[u]+1;dfs(v,u);}}int LCA(int x,int y){if(dep[x]<dep[y])swap(x,y);for(int i=19;i>=0;i--) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];if(x==y)return x;for(int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];return fa[x][0];}LL ans=(1LL<<40);void cal(int x,int lca,LL v){LL c1=0,c2=0;int h=dep[x]-dep[lca];for(int i=19;i>=0;i--)if(h&(1<<i)){if(ma[x][i]>c1) c2=c1,c1=ma[x][i];c2=max(c2,m2[x][i]);h-=(1<<i);}if(v==c1)ans=min(ans,v-c2);else ans=min(ans,v-c1);}void ask(int x,int y,LL len){int lca=LCA(x,y);cal(x,lca,len);cal(y,lca,len);}int main(){scanf("%d%d",&n,&m);for(int i=1,u,v,w;i<=m;i++){scanf("%d%d%lld",&e[i].u,&e[i].v,&e[i].w);}kruskal();dfs(1,0);for(int i=1;i<=m;i++){if(e[i].flag)continue;ask(e[i].u,e[i].v,e[i].w);}printf("%lld\n",sum+ans);return 0;}
阅读全文
0 0
- bzoj1977: [BeiJing2010]次小生成树 kruskal+倍增LCA
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree Kruskal+倍增LCA
- bzoj1977 [BeiJing2010]次小生成树 Tree(kruskal+树上倍增)
- bzoj1977 [BeiJing2010组队]次小生成树 Tree (lca+倍增)
- [BZOJ1977][Beijing2010组队][LCA][Kruskal]次小生成树
- bzoj1977: [BeiJing2010组队]次小生成树 Tree 树上倍增
- bzoj1977 [BeiJing2010组队]次小生成树 倍增
- [BZOJ1977]严格次小生成树-kruskal+倍增维护
- bzoj1977 严格的次小生成树(LCA倍增)
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree【次小生成树】【LCA】
- 1977: [BeiJing2010组队]次小生成树 Tree kruskal+倍增
- [BZOJ1977][BeiJing2010组队]次小生成树 Tree(kruskal+链剖)
- 【BZOJ1977】【MST】【LCA】[BeiJing2010组队]次小生成树 Tree 题解
- 【bzoj1977】【次小生成树】【树上倍增】
- bzoj1977: [BeiJing2010组队]次小生成树 Tree
- bzoj1977: [BeiJing2010组队]次小生成树 Tree
- BZOJ1977: [BeiJing2010组队]次小生成树 Tree
- bzoj1977 [BeiJing2010组队]次小生成树 Tree
- Redis入门很简单之六【Jedis常见操作】
- PADS LOGIC-->AD-->ORCAD CAPTURE
- 剑指offer 编程题(33):第一个只出现一次的字符
- 审批流程系统详细设计
- 简单dp&递推合集
- bzoj1977: [BeiJing2010]次小生成树 kruskal+倍增LCA
- 跨域问题(转:最近太忙啦!!!)
- Android 程序运行后,界面不显示的问题解决办法
- [android]在 Html.fromHtml 中的换行被忽略
- 一:函数模板(Function Template)
- spring系列(七):SSH整合二
- hihocoder#1347 : 小h的树上的朋友(树链剖分)
- vimtutor笔记
- luogu3389 【模板】高斯消元法