Luo Gu 1197 Star Wars

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 }
luogu1197

 

Guess you like

Origin www.cnblogs.com/edmunds/p/12752166.html