609E - Minimum spanning tree for each edge
来源:互联网 发布:java和net哪个比较好 编辑:程序博客网 时间:2024/05/29 16:13
给出一个带权图,对每个边求经过这条边的MST
先求一遍MST自然是极好的,然后对于在MST上的边,自然就是全局MST了
对于不在MST上的边,找到这个边两个端点在MST上的路径上最大权的边并去掉,然后加上询问的这条边的权就好了
#include<bits/stdc++.h>using namespace std;#define LL long long const int maxn = 212345,maxm = 212345,max_log = 18;const int ROOT = 1;vector<pair<int,LL> >edge[maxn];void Link(int st,int ed,LL v){ edge[st].push_back(make_pair(ed,v));}int deep[maxn],fa[maxn][max_log];int nofa[maxn];struct Info{ LL x; Info(LL x = 0):x(x){};};Info operator + (const Info a,const Info b){ return Info(max(a.x,b.x));}Info info[maxn][max_log];void dfs(int st,int Fa,int Deep=1){ for(int i=1;i<max_log;i++) fa[st][i] = -1,info[st][i] = Info(); fa[st][0] = Fa,deep[st] = Deep; for(auto x : edge[st]){ if(x.first == Fa) continue; dfs(x.first,st,Deep+1); info[x.first][0] = Info(x.second); }}void init(int n){ memset(fa,-1,sizeof(fa)); dfs(ROOT,-1); for (int j = 1;j < max_log;j++){ for (int i = 1;i <= n;i++){ if (fa[i][j-1] != -1){ fa[i][j] = fa[fa[i][j-1]][j-1]; info[i][j] = info[i][j-1] + info[fa[i][j-1]][j-1]; } } }}pair<int,Info> lca(int x,int y){ Info ix,iy; if (deep[x] < deep[y]) swap(x,y); for (int i = max_log-1;i >= 0;i--){ if (deep[fa[x][i]] >= deep[y]){ ix = ix + info[x][i]; x = fa[x][i]; } } if (x == y) return make_pair(x,ix); for (int i = max_log-1;i >= 0;i--){ if (fa[x][i] != fa[y][i]){ ix = ix + info[x][i]; x = fa[x][i]; iy = iy + info[y][i]; y = fa[y][i]; } } return make_pair(fa[x][0], ix/*.rev()*/+info[x][0] + info[y][0] + iy);}struct Edge{ int x,y; LL v,i; void init(int id){ scanf("%d %d %I64d",&x,&y,&v); i = id; }}edg[maxm];struct Dsu{ int arr[maxn]; void init(int n){for(int i=0;i<=n;i++) arr[i] = i;} int fnd(int x){return x == arr[x] ? x : arr[x] = fnd(arr[x]);} bool join(int x,int y){ x = fnd(x),y = fnd(y); if(x == y) return false; arr[x] = y; return true; }}dsu;int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=0;i<m;i++){ edg[i].init(i); } sort(edg,edg+m,[](Edge a,Edge b){return a.v < b.v;}); dsu.init(n); LL all = 0; for(int i=0;i<m;i++){ if(dsu.join(edg[i].x,edg[i].y)){ all += edg[i].v; Link(edg[i].x,edg[i].y,edg[i].v); Link(edg[i].y,edg[i].x,edg[i].v); } } init(n); sort(edg,edg+m,[](Edge a,Edge b){return a.i < b.i;}); for(int i=0;i<m;i++){ printf("%I64d\n",all + edg[i].v - lca(edg[i].x,edg[i].y).second.x); } return 0;}
0 0
- 609E - Minimum spanning tree for each edge
- Codeforces 609E Minimum spanning tree for each edge
- Codeforces 609E Minimum spanning tree for each edge【MST + LCA倍增】
- CodeForces 609E Minimum spanning tree for each edge (lca+最小生成树+倍增)
- codeforeces 609E Minimum spanning tree for each edge MST +LCA
- 文章标题 coderforces 609E : Minimum spanning tree for each edge (MST+LCA)
- Codeforces 609E Minimum spanning tree for each edge 树链剖分+RMQ(st算法)+最小生成树
- CodeForces 609 E.Minimum spanning tree for each edge(最小生成树-Kruskal+在线倍增LCA)
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge MST+树上路径倍增
- [树链剖分+MST] CF609E. Minimum spanning tree for each edge
- LCA+最小生成树 Codeforces609E Minimum spanning tree for each edge
- 【Educational Codeforces Round 3 E】【树链剖分】Minimum spanning tree for each edge 图构最小生成树,生成树必须包含第i条边
- Kruskal Algorithm for Minimum Spanning Tree
- Minimum Spanning Tree
- Minimum Spanning Tree SPOJ
- Kruskal’s Algorithm for finding Minimum Spanning Tree
- HDU-4408-Minimum Spanning Tree
- hdu 4408 Minimum Spanning Tree
- iOS六中传值方式之代理模式
- HDU 4324 Triangle LOVE【拓扑判断有无闭环】
- ubuntu14.4.04无法连接有线网络
- linux网络编程(三)——UDP编程
- Android开发笔记之属性动画
- 609E - Minimum spanning tree for each edge
- 数据结构实验之栈六:下一较大值(二)
- golang ssh 连接交换机
- java将两个集合合并,去除重复
- 在html页面上使用ajax传递json数据到基于express框架(node.js)的服务器
- Python学习笔记四:过程控制
- Viewpager+fragment
- (NYoj 171)聪明的kk --水dp
- php三天基础笔记(5)变量类型转换