首页 > 代码库 > bzoj1015题解
bzoj1015题解
【题意分析】
给你一张无向图,要求支持删点和询问连通块数。
【解题思路】
可以直接可持久化并查集大力艹过去。
考虑到正着删点就是倒着加点,所以并不需要可持久化。复杂度O((k+m)α(n))。
【参考代码】
当时还在玩泥巴,实现有点naive,常数奇大无比。。
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 #define REP(I,start,end) for(int I=start;I<=end;I++) 5 #define PER(I,start,end) for(int I=start;I>=end;I--) 6 using namespace std; 7 set<int> tree; 8 int n,m,k,edge=0,q[400001],father[400001],head[400001],next[400001],point[400001],sav[400001]; 9 bool destroyed[400001];10 inline void addEdge(int from,int to)11 {12 next[++edge]=head[from];13 head[from]=edge;14 point[edge]=to;15 }16 inline int getFa(int n)17 {18 if(father[n]==n)19 return n;20 return father[n]=getFa(father[n]);21 }22 int main()23 {24 scanf("%d%d",&n,&m);25 REP(i,1,m)26 {27 int u,v;28 scanf("%d%d",&u,&v);29 addEdge(u,v);30 addEdge(v,u);31 }32 scanf("%d",&k);33 memset(destroyed,0,sizeof(destroyed));34 REP(i,1,k)35 {36 scanf("%d",q+i);37 destroyed[q[i]]=true;38 }39 REP(i,0,n-1)40 father[i]=i;41 REP(i,0,n-1)42 if(!destroyed[i])43 {44 int t=head[i];45 while(t)46 {47 int p=point[t];48 if(!destroyed[p])49 father[getFa(p)]=getFa(i);50 t=next[t];51 }52 }53 tree.clear();54 REP(i,0,n-1)55 {56 int fa=getFa(i);57 if(!destroyed[i]&&tree.find(fa)==tree.end())58 tree.insert(fa);59 }60 sav[k]=tree.size();61 PER(i,k-1,0)62 {63 int P=q[i+1],t=head[P];64 destroyed[P]=false;65 tree.clear();66 while(t)67 {68 int p=point[t];69 if(!destroyed[p])70 {71 int fa2=getFa(p);72 tree.insert(fa2);73 father[getFa(P)]=fa2;74 }75 t=next[t];76 }77 sav[i]=sav[i+1]-tree.size()+1;78 }79 REP(i,0,k)80 printf("%d\n",sav[i]);81 return 0;82 }
bzoj1015题解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。