Codeforces 609E Minimum spanning tree for each edge【MST + LCA倍增】
来源:互联网 发布:如何看融资融券数据 编辑:程序博客网 时间:2024/05/16 12:10
题意:给你一个n个点和m条边的带权无向图,查询每条边的MST。
思路:先求MST,在求的过程中建树,记录代价为ans。对每条边<u, v>权值记录为c,把它加进MST里面的代价就需要去掉u->lca(u, v)->v路径上权值最大的边记录权值为Max。那么结果就是ans - Max + c。
AC代码:
#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <set>#include <vector>#define INF 0x3f3f3f3f#define eps 1e-8#define MAXN (200000+10)#define MAXM (500000)#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%.2lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define LL long long#define lson o<<1, l, mid#define rson o<<1|1, mid+1, r#define ll o<<1#define rr o<<1|1#define PI acos(-1.0)using namespace std;int N, M;struct LCA{ struct Edge{ int from, to, val, next; }; Edge edge[MAXM]; int head[MAXN], edgenum; int depth[MAXN], fa[MAXN][20], Mx[MAXN][20]; void init(){ edgenum = 0; CLR(head, -1); } void addEdge(int u, int v, int w) { Edge E = {u, v, w, head[u]}; edge[edgenum] = E; head[u] = edgenum++; } void DFS(int u, int f, int d) { depth[u] = d; fa[u][0] = f; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == f) { Mx[u][0] = edge[i].val; continue; } DFS(v, u, d+1); } } void LCA_init() { DFS(1, -1, 0); for(int i = 1; i < 20; i++) { for(int j = 1; j <= N; j++) { fa[j][i] = fa[fa[j][i-1]][i-1]; Mx[j][i] = max(Mx[j][i-1], Mx[fa[j][i-1]][i-1]); } } } int Get_path_max(int u, int v) { int ans = 0; while(depth[u] != depth[v]) { if(depth[u] < depth[v]) swap(u, v); int d = depth[u] - depth[v]; for(int i = 0; i < 20; i++) { if(d >> i & 1) { ans = max(ans, Mx[u][i]); u = fa[u][i]; } } } if(u == v) return ans; for(int i = 19; i >= 0; i--) { if(fa[u][i] != fa[v][i]) { ans = max(ans, Mx[u][i]); ans = max(ans, Mx[v][i]); u = fa[u][i]; v = fa[v][i]; } } return max(ans, max(Mx[u][0], Mx[v][0])); }};LCA L;struct Union{ int pre[MAXN]; void init() { for(int i = 1; i <= N; i++) pre[i] = i; } int Find(int p) { int child = p; while(p != pre[p]) p = pre[p]; while(child != p) { int t = pre[child]; pre[child] = p; child = t; } return p; }};Union U;struct Node{ int u, v, w;};Node num[MAXM];bool cmp(Node a, Node b){ return a.w < b.w;}int a[MAXN], b[MAXN], c[MAXN];int main(){ Ri(N); Ri(M); U.init(); L.init(); int top = 0; for(int i = 1; i <= M; i++) { Ri(a[i]); Ri(b[i]); Ri(c[i]); num[top].u = a[i]; num[top].v = b[i]; num[top++].w = c[i]; } sort(num, num+top, cmp); LL ans = 0; for(int i = 0; i < top; i++) { int u = U.Find(num[i].u); int v = U.Find(num[i].v); if(u != v) { L.addEdge(num[i].u, num[i].v, num[i].w); L.addEdge(num[i].v, num[i].u, num[i].w); ans += num[i].w; U.pre[u] = v; } } L.LCA_init(); for(int i = 1; i <= M; i++) { int Max = L.Get_path_max(a[i], b[i]); Pl(ans - Max + c[i]); } return 0;}
0 0
- Codeforces 609E Minimum spanning tree for each edge【MST + LCA倍增】
- CodeForces 609E Minimum spanning tree for each edge (lca+最小生成树+倍增)
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge MST+树上路径倍增
- CodeForces 609 E.Minimum spanning tree for each edge(最小生成树-Kruskal+在线倍增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
- 609E - Minimum spanning tree for each edge
- [树链剖分+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条边
- Codeforces 609E LCA倍增
- MST(Kruskal’s Minimum Spanning Tree Algorithm)
- 最小生成树(Minimum-Spanning-Tree, MST)
- Codeforces Round #423 Div. 2 F. Best Edge Weight (倍增法lca)(最小生成树mst)
- MST(Minimum Spanning Tree,最小生成树)
- 5.4.1 最小生成树(Minimum-Spanning-Tree,MST)
- 算法一
- AMR 文件解析及编解码流程
- NSNull&nil&Nil&NULL
- ant和antsvn构建svn自动化打包部署脚本
- NIO--JAVA NIO 入门
- Codeforces 609E Minimum spanning tree for each edge【MST + LCA倍增】
- JUnit三分钟教程 ---- 快速起步
- JMeter学习自动化badboy脚本开发技术
- JS判断是否是手机号码
- Android LayoutParams详解
- 编译原理之基于扫描器的表达式语法分析+逆波兰表达式生成
- Activity的启动模式与flag详解
- android PullToRrefresh自定义下拉刷新动画
- Embedded Linux 启动时间优化