Meaning of the questions:
Give you an undirected graph, each point omitted from the drawing, the number of interrogation points after each puncturing block in FIG communication
Ideas:
This problem can be off-line, off-line so we reverse the practice
How a reverse it? We assume that after only a starting point for all operations delete points, and calculates the number of connected blocks
After each addition points deleted in the drawing, communication, and count the number of blocks
If the re-run again, then all points on the time complexity will be fried, for the newly added point, we first add the number of the current communication block 1, if all the points of the traverse point of attachment, if able to merge, then the communication will be Save a number of blocks
Finally, the answer is like a reverse output
#include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> using namespace std; const int maxn=4e5+1000; int flag[maxn],fa[maxn]; vector<int>a[maxn]; stack<int> s,q; int find(int x){return fa[x]==x?x:(fa[x]=find(fa[x]));} int main() { int n,m,k,u,v; memset(flag,1,sizeof(flag)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&u,&v); a[u].push_back(v); a[v].push_back(u); } scanf("%d",&k); for(int i=1;i<=k;i++){ scanf("%d",&u); s.push(u); flag[u]=0; } int cnt=n-k; for(int i=0;i<n;i++) fa[i]=i; for(int i=0;i<n;i++){ if(!flag[i]) continue; else{ for(int j=0;j<a[i].size();j++){ if(flag[a[i][j]]){ int f1=find(a[i][j]),f2=find(i); if(f1!=f2) fa[f1]=find(fa[f2]),cnt--; } } } } q.push(cnt); for(int i=1;i<=k;i++){ cnt++; int x=s.top(); s.pop(); for(int j=0;j<a[x].size();j++){ if(flag[a[x][j]]){ int f1=find(a[x][j]),f2=find(x); if(f1!=f2) fa[f1]=find(fa[f2]),cnt--; } } flag[x]=1; q.push(cnt); } while(!q.empty()){ cout<<q.top()<<endl; q.pop(); } return 0; }