EtHereal_Algorithm @ 2023-01-18 16:28:59
#include <bits/stdc++.h>
#define int long long
const int N = 400005;
int fa[N], cnt = 0;
void init(int n) {
for(int i = 1; i <= n; i++) fa[i] = i;
} // the initial situation
int find(int x) {
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
} // get root(x)
bool check(int x, int y) {
int fx = find(x), fy = find(y);
return fx == fy;
} // query
void merge(int x, int y) {
if(check(x, y)) return ;
cnt--;
fa[find(x)] = find(y);
} // merge and make edge
int u[N], v[N], q[N];
bool ok[N];
using namespace std;
vector<int> G[N];
signed main() {
int n, m;
cin >> n >> m;
init(n);
cnt = n;
for(int i = 1; i <= m; i++) {
cin >> u[i] >> v[i];
u[i]++, v[i]++;
G[u[i]].push_back(v[i]);
G[v[i]].push_back(u[i]);
}
int k;
cin >> k;
for(int i = 1; i <= k; i++) cin >> q[i], q[i]++, ok[q[i]] = 1;
for(int i = 1; i <= m; i++) {
if(ok[i]) continue;
for(auto x : G[i]) {
if(ok[x]) continue;
merge(x, i);
}
}
stack<int> ans;
for(int i = k; i; i--) {
ans.push(cnt - i);
int x = q[i];
ok[x] = 0;
for(auto y : G[x]) {
if(ok[y]) continue;
merge(y, x);
}
}
cout << cnt << endl;
while(!ans.empty()) {
cout << ans.top() << endl;
ans.pop();
}
return 0;
}
WA on #9.
目测是没把所有边都 merge
一遍,但是我觉得逻辑上是都 merge
的啊。
by EtHereal_Algorithm @ 2023-01-18 17:17:14
破案了,
顺便留给后人用。