Title link: https://www.luogu.com.cn/problem/P1197
You can think about it in reverse, and gradually add points from the final state, and merge the points with the points. Use a cnt to dynamically maintain the number of connected blocks: when a new point is added, cnt ++, every time after the collection is merged, if the root node is in the same set, it will not be merged, naturally the cnt will not change; if the root node is in a different set In the merger, the number of connected blocks decreases by 1, cnt--.
For the specific implementation, I opened several arrays and used the structure to store the left and right points of the road. P [i] = 0 means that point i has not been destroyed. Q [i] stores the order of points in reverse order. Ans stores the answer in reverse order, and then uses A vector stores the points adjacent to each point. At the beginning, merge the last case: if p [r [i] .x] = 0 and p [r [i] .y] = 0, then merge; then follow the above process of gradually adding points, if the newly added points The adjacent point v [q [i]] [j] of q [i] is not destroyed, ie p [v [q [i]] [j]] = 0, then merge q [i] and v [q [i ]] [j], and dynamically update cnt.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=4000+10; 4 struct st{int x,y;} r[maxn]; 5 vector<int> v[maxn]; 6 int p[maxn],par[maxn],q[maxn],ans[maxn]; 7 int n,m,i,j,k,t; 8 set<int> s; 9 10 int find(int u){return par[u]==u?u:par[u]=find(par[u]);} 11 12 int main(){ 13 //freopen("luogu1197.txt","r",stdin); 14 scanf("%d%d",&n,&m); 15 for (i=1;i<=m;i++) { 16 scanf("%d%d",&r[i].x,&r[i].y); 17 v[r[i].x].push_back(r[i].y);v[r[i].y].push_back(r[i].x); 18 } 19 scanf("%d",&k); 20 memset(p,0,sizeof(p)); 21 for (i=1;i<=k;i++){ 22 int star;scanf("%d",&star); 23 p[star]=1;q[k-i+1]=star; 24 } 25 for (i=0;i<n;i++) par[i]=i; 26 for (i=1;i<=m;i++) 27 if (p[r[i].x]==0&&p[r[i].y]==0){ 28 int xx=find(r[i].x);int yy=find(r[i].y); 29 if (xx!=yy) par[xx]=yy; 30 } 31 s.clear(); 32 for (i=0;i<n;i++) { 33 par[i]=find(par[i]); 34 if (p[i]==0) s.insert(par[i]); 35 } 36 int cnt=s.size(); 37 ans[k+1]=cnt; 38 for (i=1;i<=k;i++){ 39 p[q[i]]=0;cnt++; 40 for (j=0;j<v[q[i]].size();j++) 41 if (p[v[q[i]][j]]==0) { 42 int xx=find(q[i]);int yy=find(v[q[i]][j]); 43 if (xx!=yy){ 44 par[xx]=yy;cnt--; 45 } 46 } 47 ans[k-i+1]=cnt; 48 } 49 for (i=1;i<=k+1;i++) printf("%d\n",ans[i]); 50 //fclose(stdin); 51 return 0; 52 }