【JSOI2008】星球大战

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1197


也不算太难吧,正着想先建图再拆点不太好实现,不如先把所有数据读入,然后倒着添加点。

然后就是对代码能力和人品的考验了,,,一个小做法考虑的不好就导致只有10分。。。

 1 #include <cstdio>
 2 
 3 inline int get_num() {
 4     int num = 0;
 5     char c = getchar();
 6     while (c < '0' || c > '9') c = getchar();
 7     while (c >= '0' && c <= '9')
 8         num = num * 10 + c - '0', c = getchar();
 9     return num;
10 }
11 
12 const int maxn = 4e5 + 5, maxm = 2e5 + 5;
13 
14 int fa[maxn], head[maxn], eid;
15 
16 struct Edge {
17     int u, v, next;
18 } edge[2 * maxm];
19 
20 inline void insert(int u, int v) {
21     edge[++eid].u = u;
22     edge[eid].v = v;
23     edge[eid].next = head[u];
24     head[u] = eid;
25 }
26 
27 int dj_find(int i) {
28     if (i == fa[i]) return i;
29     else return fa[i] = dj_find(fa[i]);
30 }
31 
32 inline void dj_merge(int a, int b) {
33     a = dj_find(a), b = dj_find(b);
34     if (a != b) fa[a] = b;
35 }
36 
37 int vis[maxn], del[maxn], out[maxn];
38 
39 int main() {
40     int n, m, x, y, k, ans;
41     n = get_num(), m = get_num();
42     for (int i = 1; i <= m; ++i) {
43         x = get_num(), y = get_num();
44         insert(x, y);
45         insert(y, x);
46     }
47     k = get_num();
48     for (int i = 1; i <= k; ++i)
49         vis[del[i] = get_num()] = 1;
50     for (int i = 0; i < n; ++i) fa[i] = i;
51     ans = n - k;
52     for (int i = 0; i < n; ++i) {
53         if (vis[i]) continue;
54         for (int j = head[i]; j; j = edge[j].next) {
55             int u = edge[j].u, v = edge[j].v;
56             if (vis[v]) continue;
57             if (dj_find(u) != dj_find(v)) {
58                 dj_merge(u, v);
59                 --ans;
60             }
61         }
62     }
63     out[k] = ans;
64     for (int i = k; i >= 1; --i) {
65         int u = del[i];
66         vis[u] = 0, ++ans;
67         for (int j = head[u]; j; j = edge[j].next) {
68             int v = edge[j].v;
69             if (vis[v]) continue;
70             if (dj_find(u) != dj_find(v)) {
71                 dj_merge(u, v);
72                 --ans;
73             }
74         }
75         out[i - 1] = ans;
76     }
77     for (int i = 0; i <= k; ++i) printf("%d
", out[i]);
78     return 0;
79 }
AC代码
原文地址:https://www.cnblogs.com/Mr94Kevin/p/9821777.html