码迷,mamicode.com
首页 > Web开发 > 详细

bzoj 1015[JSOI2008]星球大战starwar - 并查集

时间:2018-02-10 11:11:54      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:include   nbsp   jsoi2008   std   for   find   src   技术   display   

比较水的一道题

并查集的性质是很好维护加边的操作,却不能支持删边

所以我们只需倒着做一遍就能将删边转为加边

技术分享图片
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #define LL long long 
  6 
  7 using namespace std;
  8 
  9 const int MAXM = 2e5 + 10;
 10 const int MAXN = 4e5 + 10;
 11 int N, M, K;
 12 int cnt = 0;
 13 int ans[MAXN];
 14 int exs[MAXN];
 15 int x, y;
 16 int father[MAXN];
 17 int head[MAXN];
 18 
 19 int find(int x)
 20 {
 21     if(x != father[x]) {
 22         father[x] = find(father[x]);
 23     }
 24     return father[x];
 25 }
 26 struct edge {
 27     int use;
 28     int v;
 29     int next;
 30 } g[MAXM * 3];
 31 
 32 void addedge(int u, int v)
 33 {
 34     g[cnt].v = v;
 35     g[cnt].use = 0;
 36     g[cnt].next = head[u];
 37     head[u] = cnt++;
 38 }
 39 int d[MAXN];
 40 inline LL read()
 41 {
 42     LL x = 0, w = 1; char ch = 0;
 43     while(ch < 0 || ch > 9) {
 44         if(ch == -) {
 45             w = -1;
 46         }
 47         ch = getchar();
 48     }
 49     while(ch >= 0 && ch <= 9) {
 50         x = x * 10 + ch - 0;
 51         ch = getchar();
 52     }
 53     return x * w;
 54 }
 55 
 56 void init()
 57 {
 58     memset(head, -1, sizeof head);
 59     for(int i = 0; i < N; i++) {
 60         father[i] = i;
 61     }
 62 }
 63 int main()
 64 {
 65     N = read(), M = read();
 66     init();
 67     for(int i = 1; i <= M; i++) {
 68         int u = read(), v = read();
 69         addedge(u, v);
 70         addedge(v, u);
 71     }
 72     K = read();
 73     for(int i = 1; i <= K; i++) {
 74         int k = read();
 75         d[i] = k;
 76         exs[k] = 1;
 77     }
 78     ans[K + 1] = N - K;
 79 /*    for(int i = 0; i < N; i++) {
 80         cout<<exs[i]<<" ";
 81     }
 82     cout<<endl;
 83     cout<<find(2)<<" "<<find(6)<<endl;*/
 84     for(int i = 0; i < N; i++) {
 85         if(!exs[i]) {
 86             for(int j = head[i]; j != -1; j = g[j].next) {
 87                 int to = g[j].v;
 88                 if(!g[j ^ 1].use && !exs[to]) {
 89                     g[j].use = 1;
 90                     x = find(to), y = find(i);
 91                     if(x != y) {
 92                         father[y] = x;
 93                         ans[K + 1]--;
 94                     }
 95                 }
 96             }
 97         }
 98     }
 99     for(int i = K; i >= 1; i--) {
100         int k = d[i];
101         ans[i] = ans[i + 1] + 1;
102         for(int j = head[k]; j != -1; j = g[j].next) {
103             int to = g[j].v;
104             if(!exs[to] && !g[j ^ 1].use) {
105                 g[j].use = 1;
106                 x = find(to), y = find(k);
107                 if(x != y) {
108                     father[y] = x;
109                     ans[i]--;
110                 }
111             }
112         }
113         exs[k] = 0;
114     }
115     for(int i = 1; i <= K + 1; i++) {
116         printf("%d\n", ans[i]);
117     }
118     return 0;
119 }
120 
121 /*
122 8 13
123 0 1
124 1 6
125 6 5
126 5 0
127 0 6
128 1 2
129 2 3
130 3 4
131 4 5
132 7 1
133 7 2
134 7 6
135 3 6
136 5
137 1
138 6
139 3
140 5
141 7
142 
143 
144 */
View Code

 

bzoj 1015[JSOI2008]星球大战starwar - 并查集

标签:include   nbsp   jsoi2008   std   for   find   src   技术   display   

原文地址:https://www.cnblogs.com/wuenze/p/8438119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!