sgu529. It's Time to Repair the Roads 简化版动态最小生成树
2013-02-09 13:21
495 查看
题目大意:
给出n个点m条边,然后给出q个询问,表示把目前第numi条边的边权修改为di后的mst。
一个分治算法
两个重要的操作 Contraction 和 Reduction 操作。 详见论文《Offline Algorithms for Dynamic Minimum Spanning Tree Problems》
给出n个点m条边,然后给出q个询问,表示把目前第numi条边的边权修改为di后的mst。
一个分治算法
两个重要的操作 Contraction 和 Reduction 操作。 详见论文《Offline Algorithms for Dynamic Minimum Spanning Tree Problems》
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define MAXT 50010 #define MAXM 100010 #define MAXN 50010 using namespace std; const long long INF = 1LL <<40; int n,m,q; int x[MAXM],y[MAXM],num[MAXM],d[MAXM],f[MAXN],ord[MAXM],t[MAXN]; long long z[MAXM],c[MAXM], answer; struct Edge{ int cnt; int a[MAXM*5],b[MAXN*5]; inline void renew(int); inline void merge(int u,int v); inline int find(int v); }edge[20]; inline void Edge::renew(int top = 0) { for (;cnt != top; --cnt) f[a[cnt]] = b[cnt]; } inline void Edge::merge(int v,int u) { int _v = find(v); int _u = find(u); a[++cnt] = _v; b[cnt] = f[_v]; f[_v] = _u; } inline int Edge::find(int v) { if (!f[v]) return v; int ret = v; while (f[ret]) ret = f[ret]; while (f[v] != ret) { a[++cnt] = v; b[cnt] = f[v]; f[v] = ret; v = b[cnt]; } return ret; } void Qsort(int l,int r) { long long k = z[ord[(l+r)/2]]; int i = l, j = r; while (i<j) { while (z[ord[i]] < k) i++; while (z[ord[j]] > k) j--; if (i<=j) swap(ord[i++], ord[j--]); } if (i<r) Qsort(i,r); if (l<j) Qsort(l,j); } inline void work(int l ,int r,int dep) { Edge &e = edge[dep]; e.cnt = 0; if (l>r) return ; if (l == r) { z[num[l]] = c[num[l]] = d[l]; Qsort(1,m); long long ans = answer; for (int i = 1; i <= m;++i) if (e.find(x[ord[i]]) != e.find(y[ord[i]])) { ans+=z[ord[i]]; e.merge(x[ord[i]],y[ord[i]]); } e.renew(); printf("%lld\n",ans); return ; } int temp_m = m; long long temp_ans = answer; //Contrresume; for (int i = l; i <= r; ++i) z[num[i]] = -INF; Qsort(1,m); t[0] = 0; for (int i = 1; i <= m; ++i) { if (e.find(x[ord[i]]) != e.find(y[ord[i]])) { if (z[ord[i]] != -INF) t[++t[0]] = ord[i]; e.merge(x[ord[i]],y[ord[i]]); } } e.renew(); for (int i = 1; i <= t[0] ; ++i) { e.merge(x[t[i]], y[t[i]]); answer +=z[t[i]]; } int temp_cnt = e.cnt; //Reduction for (int i = l; i <= r; ++i) z[num[i]] = INF; Qsort(1,m); t[0] =0; for (int i = 1; i <= m; ++i) { if (e.find(x[ord[i]]) != e.find(y[ord[i]])) e.merge(x[ord[i]], y[ord[i]]); else { if (z[ord[i]] != INF) t[++t[0]] = i; } } for (int i = t[0]; i ; --i) swap(ord[t[i]],ord[m--]); e.renew(temp_cnt); for (int i =l ; i<=r; ++i) z[num[i]] = c[num[i]]; work(l,(l+r)/2, dep+1); work((l+r)/2+1,r,dep+1); e.renew(); answer = temp_ans; m = temp_m; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m ;++i) { scanf("%d %d %d", &x[i],&y[i],&z[i]); c[i] = z[i]; ord[i] = i; } scanf("%d",&q); Qsort(1,m); for (int i = 1; i <= q; ++i) scanf("%d %d", &num[i], &d[i]); work(1,q,0); return 0; }
相关文章推荐
- 简化document.createElement("div")动态生成层方法 (转)
- 完全动态最小生成树(sgu529,HNOI2010city)
- 简化document.createElement("div")动态生成层方法
- 杭电1301--Jungle Roads(最小生成…
- POJ 2349&&ZOJ 1914 Arctic Network(kuangbin带你飞 专题六:最小生成树)
- hoj12616 Median Tree ——最小生成树入门题&&比赛残留题_Kruscal算法
- 畅通工程 hdu 1232 && HDU - 1863 (并查集+最小生成树)
- POJ 2377 Bad Cowtractors【最小生成树变形&&最大生成树】
- <模板>poj2031 Building a Space Station(最小生成树)
- UVA 10600 - ACM Contest and Blackout(最小生成树&次小生成树)
- hdoj 1233 还是畅通工程【最小生成树 kruskal && prim】
- HDOJ 1863 畅通工程 最小生成树 kruskal && prim
- bzoj2001 [Hnoi2010]City 城市建设 动态最小生成树
- ZOJ 【2108】Agri-Net(最小生成树)模拟生成树&普利姆算法
- hdu1575畅通工程再续【最小生成树】cruskal&prim
- 并查集&&最小生成树(模板)
- [C++]最小生成树--Prim算法&Kruskal算法
- hdu 还是畅通工程 (基础)(最小生成树)(Prim算法 && Kruskal算法)
- HDU--1233:还是畅通工程 (并查集 & 最小生成树Prim)
- hdu 畅通工程再续(最小生成树)(Prim算法 && Kruskal算法)