bzoj 2001 CITY 城市建设 cdq分治

题目传送门

题解:

对整个修改的区间进行分治。对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-inf,跑一遍最小生成树,然后对于一条树边并且他的权值不为-inf,那么这条边一定就是树边了。然后我们把这些点都缩成一个点。然后,我们继续对当前修改区间来说,我们把要修改的边的边权都修改成inf,跑一遍最小生成树,然后对于一条非树边来说,他的边权不为inf,那么这条边一点是非树边了,然后我们每层缩点,减边,这样图就会越来越小,然后当l == r的时候,我们还原修改操作,最后把跑最小生成树计算答案。

一道神奇的cdq题目。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define lch(x) tr[x].son[0]
 12 #define rch(x) tr[x].son[1]
 13 #define max3(a,b,c) max(a,max(b,c))
 14 #define min3(a,b,c) min(a,min(b,c))
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 1e5 + 100;
 20 struct Node{
 21     int u, v, c, id;
 22     bool operator < (const Node & x) const{
 23         return c < x.c;
 24     }
 25 }e[20][N], f[N], g[N];
 26 int a[N], b[N], ct[N], mapid[N];
 27 int pre[N];
 28 int Find(int x){
 29     if(x == pre[x]) return x;
 30     return pre[x] = Find(pre[x]);
 31 }
 32 LL ans[N];
 33 void Clear(int tot){
 34     for(int i = 1; i <= tot; i++){
 35         pre[f[i].u] = f[i].u;
 36         pre[f[i].v] = f[i].v;
 37     }
 38 }
 39 void contraction(int &tot, LL &sum){
 40     Clear(tot);
 41     sort(f+1, f+1+tot);
 42     int u, v, zz = 0;
 43     for(int i = 1; i <= tot; i++){
 44         u = Find(f[i].u), v = Find(f[i].v);
 45         if(u != v){
 46             pre[u] = v;
 47             if(f[i].c != -inf){
 48                 sum += f[i].c;
 49                 g[++zz] = f[i];
 50             }
 51         }
 52     }
 53     Clear(tot);
 54     for(int i = 1; i <= zz; i++){
 55         u = Find(g[i].u); v = Find(g[i].v);
 56         pre[u] = v;
 57     }
 58     zz = 0;
 59     for(int i = 1; i <= tot; i++){
 60         u = Find(f[i].u), v = Find(f[i].v);
 61         if(u != v){
 62             f[++zz] = f[i];
 63             f[zz].u = u;
 64             f[zz].v = v;
 65             mapid[f[i].id] = zz;
 66         }
 67     }
 68     tot = zz;
 69     return ;
 70 }
 71 void reduction(int &tot){
 72     Clear(tot);
 73     sort(f+1, f+1+tot);
 74     int u, v, zz = 0;
 75     for(int i = 1; i <= tot; i++){
 76         u = Find(f[i].u); v = Find(f[i].v);
 77         if(u != v){
 78             pre[u] = v;
 79             f[++zz] = f[i];
 80         }
 81         else if(f[i].c == inf)
 82             f[++zz] = f[i]
 83     }
 84     tot = zz;
 85     return ;
 86 }
 87 void cdq(int l, int r, int now, int tot, LL sum){
 88     if(l == r) ct[a[l]] = b[l];
 89     for(int i = 1; i <= tot; i++){
 90         e[now][i].c = ct[e[now][i].id];
 91         mapid[e[now][i].id] = i;
 92         f[i] = e[now][i];
 93     }
 94     if(l == r){
 95         ans[l] = sum;
 96         Clear(tot);
 97         sort(f+1, f+1+tot);
 98         int u, v;
 99         for(int i = 1; i <= tot; i++){
100             u = Find(f[i].u), v = Find(f[i].v);
101             if(u != v){
102                 pre[u] = v;
103                 ans[l] += f[i].c;
104             }
105         }
106         return ;
107     }
108     for(int i = l; i <= r; i++) f[mapid[a[i]]].c = -inf;
109     contraction(tot, sum);
110     for(int i = l; i <= r; i++) f[mapid[a[i]]].c = inf;
111     reduction(tot);
112     for(int i = 1; i <= tot; i++) e[now+1][i] = f[i];
113     int mid = l+r >> 1;
114     cdq(l, mid, now+1, tot, sum);
115     cdq(mid+1, r, now+1, tot, sum);
116 
117 }
118 int main(){
119     int n, m, q;
120     scanf("%d%d%d", &n, &m, &q);
121     for(int i = 1; i <= m; i++){
122         scanf("%d%d%d", &e[0][i].u, &e[0][i].v, &e[0][i].c);
123         e[0][i].id = i;
124         ct[i] = e[0][i].c;
125     }
126     for(int i = 1; i <= q; i++)
127         scanf("%d%d", &a[i], &b[i]);
128     cdq(1,q,0,m,0);
129     for(int i = 1; i <= q; ++i)
130         printf("%lld\n", ans[i]);
131     return 0;
132 }
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9791589.html
今日推荐