codeforces 733F (树链剖分 RMQ)
来源:互联网 发布:java外包公司怎么找 编辑:程序博客网 时间:2024/05/29 15:18
题目链接:点击这里
题意:给出一个图,每条边有权值和花费c,每次花费c能使的权值-1。给出一个预算,求减完权值后的一个最小生成树。
观察到最优的策略必然是只减少一条边的权值。于是首先先将初始权值做一次最小生成树。然后枚举所有的边,如果这条边是生成树的边,求出预算都花在这条边上的结果;如果非树边,就在这条边两个点到他们的LCA路径上求出树边的最大值,这个最大值用轻重链剖分维护,(也可以往上倍增)树链上无修改的最大值可以用RMQ维护,然后求出扣掉这个最大树边,加进去这条边的最终结果。中间过程维护一下最小值。
#include <bits/stdc++.h>using namespace std;#define Clear(x,y) memset (x,y,sizeof(x));#define maxn 200005#define maxm maxn<<1int n, m;long long w[maxn], c[maxn], S;struct E { int u, v, id; bool operator < (const E &a) const { return w[id] < w[a.id]; }}e[maxn];bool in_mst[maxn];//每条边在不在mst中struct node { int v, next, id;}edge[maxm];int head[maxn], cnt;int top[maxn], fa[maxn], deep[maxn], num[maxn], p[maxn], fp[maxn];int son[maxn], pos;long long MST;void add_edge (int u, int v, int id) { edge[cnt].id = id; edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;}int Find (int x) {return fa[x] == x ? fa[x] : fa[x] = Find (fa[x]);}void init () { MST = 0; Clear (in_mst, 0); Clear (head, -1); cnt = 0; for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= m; i++) {// cout << e[i].id << " "; int p1 = Find (e[i].u), p2 = Find (e[i].v); if (p1 != p2) { fa[p1] = p2; MST += w[e[i].id]; in_mst[e[i].id] = 1; add_edge (e[i].u, e[i].v, e[i].id); add_edge (e[i].v, e[i].u, e[i].id); } } //cout << endl; Clear (son, -1); pos = 0; //for (int i = 1; i <= m; i++) if (in_mst[i]) cout << i << " "; cout << endl; //cout << MST << endl;}void dfs1 (int u, int pre, int d) { deep[u] = d; fa[u] = pre; num[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v == pre) continue; dfs1 (v, u, d+1); num[u] += num[v]; if (son[u] == -1 || num[v] > num[son[u]]) son[u] = v; }}#define pii pair<long long, int>#define mp make_pairpii dp[maxn][20];pii min (pii a, pii b) { return a < b ? a : b;}pii max (pii a, pii b) { return a < b ? b : a;}void getpos (int u, int sp) { top[u] = sp; p[u] = pos++; fp[p[u]] = u; if (son[u] == -1) return ; getpos (son[u], sp); for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v == fa[u] || v == son[u]) continue; getpos (v, v); }}void dfs2 (int u) { for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v == fa[u]) continue; dp[p[v]][0] = mp (w[edge[i].id], edge[i].id); dfs2 (v); }}void rmq_init () { dfs2 (1); for (int j = 1; (1<<j) <= n; j++) { for (int i = 0; i+(1<<j)-1 < n; i++) { dp[i][j] = max (dp[i][j-1], dp[i+(1<<(j-1))][j-1]); } }}pii rmq (int l, int r) { int k = 0; while ((1<<(k+1)) <= r-l+1) k++; return max (dp[l][k], dp[r-(1<<k)+1][k]);}pii query (int u, int v) { int f1 = top[u], f2 = top[v]; pii tmp = mp (0, 0); while (f1 != f2) { if (deep[f1] < deep[f2]) { swap (u, v); swap (f1, f2); } tmp = max (tmp, rmq (p[f1], p[u])); u = fa[f1]; f1 = top[u]; } if (u == v) return tmp; if (deep[u] > deep[v]) swap (u, v); return max (tmp, rmq (p[son[u]], p[v]));}void solve () { dfs1 (1, 0, 0); getpos (1, 1); rmq_init (); long long ans = 1e15; int pos = -1, del = -1; for (int i = 1; i <= m; i++) { long long tmp; if (in_mst[e[i].id]) { tmp = MST-S/c[e[i].id]; if (tmp < ans) { ans = tmp; pos = e[i].id; } } else { pii Min = query (e[i].u, e[i].v); tmp = MST-w[Min.second]+w[e[i].id]-S/c[e[i].id]; if (tmp < ans) { ans = tmp; pos = e[i].id; del = Min.second; } } } cout << ans << "\n"; for (int i = 1; i <= m; i++) if (in_mst[i] || i == pos) { if (i == del) continue; cout << i << " "; if (i == pos) cout << w[i]-S/c[i] << "\n"; else cout << w[i] << "\n"; }}int main () { //freopen ("more.in", "r", stdin); ios::sync_with_stdio (0); cin >> n >> m; for (int i = 1; i <= m; i++) cin >> w[i]; for (int i = 1; i <= m; i++) cin >> c[i]; for (int i = 1; i <= m; i++) { cin >> e[i].u >> e[i].v; e[i].id = i; } cin >> S; sort (e+1, e+1+m); init (); solve (); return 0;}
0 0
- codeforces 733F (树链剖分 RMQ)
- CodeForces 653F Paper task(rmq+二分+后缀数组)
- codeforces 733F. Drivers Dissatisfaction
- Codeforces 659F F
- Circular RMQ CodeForces
- codeforces 485D (RMQ)
- Codeforces 234 F. Fence
- 【Codeforces 500F】Dp
- codeforces 234F - Fence
- F-Logo Turtle codeforces
- 【CODEFORCES】 F. Ant colony
- Codeforces 567F
- CodeForces 241F Race
- Codeforces 611F 思维
- Codeforces 542F 构造
- codeforces 626f
- codeforces 622f
- codeforces 628F
- [LA3983][DP][单调队列]捡垃圾的机器人
- 【JAVA语言程序设计第十版 11.2】+ 多态 + 继承
- 动态规划,递推,高精度(Matches,uva 11375)
- 关于CSV查找指定行列的一些微小的工作
- C——extern
- codeforces 733F (树链剖分 RMQ)
- VXLAN 概念(Part I) - 每天5分钟玩转 OpenStack(108)
- tomas-hardy
- 11月03日 星期四
- (四)工厂方法模式详解(另附简单工厂的死亡之路)
- OpenGL深度测试
- 学习javaScript核心ECMAScript(一)-----页面中的js
- Android产品研发(二十二)-->Android实用调试技巧
- VTK修炼之道3_VTK体系结构2