Croc Champ 2013

链接:

http://codeforces.com/contest/292/problem/D

题意:

给你一个图,n个点,m条边

每次询问l,r   问如果删除第l条边到第r条边之间的所有边,有多少联通分量

题解:

前缀并查集和后缀并查集就可以了 

代码:

31 int n, m, k;
32 int x[MAXN], y[MAXN];
33 int P[MAXN][510];
34 int rP[MAXN][510];
35 int PP[510];
36 int vis[510];
37 
38 int find(int *par,int x) {
39     return par[x] = par[x] == x ? x : find(par, par[x]);
40 }
41 
42 void unite(int *par, int x, int y) {
43     int a = find(par, x), b = find(par, y);
44     if (a != b) par[a] = b;
45 }
46 
47 int main() {
48     ios::sync_with_stdio(false), cin.tie(0);
49     cin >> n >> m;
50     rep(i, 1, m + 1) cin >> x[i] >> y[i];
51     rep(i, 1, n + 1) P[0][i] = i;
52     rep(i, 1, m + 1) {
53         rep(j, 1, n + 1) P[i][j] = P[i - 1][j];
54         unite(P[i], x[i], y[i]);
55     }
56     rep(i, 1, n + 1) rP[m + 1][i] = i;
57     per(i, 1, m + 1) {
58         rep(j, 1, n + 1) rP[i][j] = rP[i + 1][j];
59         unite(rP[i], x[i], y[i]);
60     }
61     cin >> k;
62     while (k--) {
63         int l, r;
64         cin >> l >> r;
65         rep(i, 1, n + 1) PP[i] = P[l - 1][i];
66         rep(i, 1, n + 1) unite(PP, i, find(rP[r + 1], i));
67         memset(vis, 0, sizeof(vis));
68         int ans = 0;
69         rep(i, 1, n + 1) if (!vis[find(PP, i)]) {
70             ans++;
71             vis[find(PP, i)] = 1;
72         }
73         cout << ans << endl;
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/baocong/p/7391426.html