文章标题 coderforces 609E : Minimum spanning tree for each edge (MST+LCA)
来源:互联网 发布:淘宝双11销售额 编辑:程序博客网 时间:2024/06/05 20:00
Minimum spanning tree for each edge
题意:就是有一个无向图n个点,m条边,然后对于第i条边,然后要们求出包含第i条边是最小生成树的权值是多少,然后输出m个值。
分析:首先先求出最小生成树,然后通过这个,然后对于每一条边(u,v),只需要求出u-> v这条路径上的最大边,用这条边替换(u,v)这条边即可,问题就转化成求u到v路径上的最大边,而求最大边可以用LCA中的倍增方式求出来,在倍增的过程中保存u->lca的最大边,和v->lca的最大边。
代码:
#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<vector>#include<math.h>#include<map>#include<queue> #include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;typedef pair<int,int> pii;const int maxn=2e5+10;typedef long long ll;int n,m;ll ans;//最小生成树的结果//lcastruct node { int to,nex,w;}E[maxn*2];int tot,head[maxn];void init(){ tot=0; memset (head,-1,sizeof (head));}void addedge(int u,int v,int w){ E[tot]=node{v,head[u],w}; head[u]=tot++; }const int LOG=20;int par[maxn][LOG],Maxedge[maxn][LOG],dep[maxn];void dfs(int u,int pre,int depth){ dep[u]=depth; par[u][0]=pre; for (int i=head[u];i!=-1;i=E[i].nex){ int v=E[i].to; if (v==pre){ Maxedge[u][0]=E[i].w; continue; } dfs(v,u,depth+1); }}void work(){ dfs(1,-1,1); for (int i=1;i<LOG;i++){ for (int j=1;j<=n;j++){ par[j][i]=par[par[j][i-1]][i-1]; Maxedge[j][i]=max(Maxedge[j][i-1],Maxedge[par[j][i-1]][i-1]); } }}int lca(int u,int v){ if (dep[u]<dep[v])swap(u,v); int d=dep[u]-dep[v]; int res=0; for (int i=0;i<LOG;i++){ if (d&(1<<i)){ res=max(res,Maxedge[u][i]); u=par[u][i]; } } if (u==v)return res; for (int i=LOG-1;i>=0;i--){ if (par[u][i]!=par[v][i]){ res=max(res,Maxedge[u][i]); res=max(res,Maxedge[v][i]); u=par[u][i];v=par[v][i]; } } return max(res,max(Maxedge[u][0],Maxedge[v][0]));}//MSTstruct Edge{ int u,v; ll w; int id; bool operator <(const Edge &t)const { return w<t.w; } }edge[maxn]; int fa[maxn];int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]);}void MST(){ ans=0; for (int i=1;i<=n;i++)fa[i]=i; sort(edge+1,edge+1+m); int cnt=0; for (int i=1;i<=m;i++){ int u=edge[i].u,v=edge[i].v; ll w=edge[i].w; int fu=find(u),fv=find(v); if (fu!=fv){ fa[fu]=fv; addedge(u,v,w);//加边 addedge(v,u,w); ans+=w; cnt++; } if (cnt==n-1)break; }}ll a[maxn];int main (){ while (scanf ("%d%d",&n,&m)!=EOF){ init(); for (int i=1;i<=m;i++){ scanf ("%d%d%lld",&edge[i].u,&edge[i].v,&edge[i].w); edge[i].id=i; } MST(); work(); for (int i=1;i<=m;i++){ a[edge[i].id]=ans-lca(edge[i].u,edge[i].v)+edge[i].w; } for (int i=1;i<=m;i++){ printf ("%lld\n",a[i]); } } return 0;}
阅读全文
0 0
- 文章标题 coderforces 609E : Minimum spanning tree for each edge (MST+LCA)
- Codeforces 609E Minimum spanning tree for each edge【MST + LCA倍增】
- codeforeces 609E Minimum spanning tree for each edge MST +LCA
- CodeForces 609E Minimum spanning tree for each edge (lca+最小生成树+倍增)
- CodeForces 609 E.Minimum spanning tree for each edge(最小生成树-Kruskal+在线倍增LCA)
- 609E - Minimum spanning tree for each edge
- Codeforces 609E Minimum spanning tree for each edge
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge MST+树上路径倍增
- [树链剖分+MST] CF609E. Minimum spanning tree for each edge
- Codeforces 609E Minimum spanning tree for each edge 树链剖分+RMQ(st算法)+最小生成树
- LCA+最小生成树 Codeforces609E Minimum spanning tree for each edge
- 【Educational Codeforces Round 3 E】【树链剖分】Minimum spanning tree for each edge 图构最小生成树,生成树必须包含第i条边
- MST(Minimum Spanning Tree,最小生成树)
- 5.4.1 最小生成树(Minimum-Spanning-Tree,MST)
- MST(Kruskal’s Minimum Spanning Tree Algorithm)
- 最小生成树(Minimum-Spanning-Tree, MST)
- 朱刘算法(Directed Minimum Spanning Tree/Directed MST/Minimum Arborescence/Optimum Branchings)
- 最小生成树MST(Minimum Spanning Tree)-普里姆(Prim)算法
- CSS3新增特性
- 3.MongoDB数据查询
- jdk1.7 try-with-resource
- loadrunner Web_类函数之web_save_header()
- 【mysql】事务 运行原理 概述
- 文章标题 coderforces 609E : Minimum spanning tree for each edge (MST+LCA)
- C语言基础数据类型与运算符号复习记录
- 弹出框
- 读书笔记-《Java NIO》:第三章 通道(4)
- 【LeetCode算法练习(C++)】Roman to Integer
- Xcode(8.3.3)编辑时闪退
- 3.1 栈及其基本应用
- C++中变量默认初始化规则
- PHP正则替换函数preg_replace和preg_replace_callback使用总结