Educational Codeforces Round 37 (Rated for Div. 2) 920E E. Connected Components?
题
OvO http://codeforces.com/contest/920/problem/E
解
模拟一遍……
1.首先把所有数放到一个集合 s 中,并创建一个队列 que
2.然后每次随便取一个数,并且从集合中删除这个数,将这个数放入 que
3.取 que 首元素,记为 now,然后枚举集合 s,每次找到 s 中和 now 相连的元素 x,从 s 中删除元素 x,并且把 x 放入 que 中。
4.如果 s 不为空,回到步骤2
可见就是一个模拟,至于复杂度,计算如下。
由于每个数字只会从集合 s 中删除一次。步骤3中枚举集合 s 元素的操作中,记成功从集合 s 中删除元素的为有效操作,反之为无效操作,则每一次有效操作必然会使 s 中元素数量减1,所以有效操作复杂度为O(n)。而每次无效操作则必然会使用到一对题目所给的 (x,y),其中 x 与 y 不相连,可见无效操作复杂度为 O(m)。
其他复杂度计算显然。加起来不会超时。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <map> 7 #include <set> 8 #include <queue> 9 10 using namespace std; 11 12 const int M=2e5+44; 13 const int N=2e5; 14 15 vector<int> mp[M]; 16 queue<int> que; 17 set<int> s; 18 int n,m; 19 int lans,ans[M]; 20 21 void init() 22 { 23 for(int i=0;i<=N;i++) 24 mp[i].clear(); 25 s.clear(); 26 lans=0; 27 } 28 29 bool isConnected(int a,int b) 30 { 31 vector<int>::iterator it=lower_bound(mp[a].begin(),mp[a].end(),b); 32 if(it==mp[a].end() || *it!=b) return true; 33 return false; 34 } 35 36 void solve() 37 { 38 queue<int> dlt; 39 int now,tmp; 40 set<int>::iterator it,tmp_it; 41 for(int i=1;i<=n;i++) 42 s.insert(i); 43 while(s.size()>0) 44 { 45 while(!que.empty()) que.pop(); 46 while(!dlt.empty()) dlt.pop(); 47 lans++; ans[lans]=0; 48 it=s.begin(); now=*it; 49 // cout<<now<<' '; 50 s.erase(it); ans[lans]++; 51 que.push(now); 52 while(!que.empty()) 53 { 54 now=que.front(); que.pop(); 55 for(it=s.begin();it!=s.end();it++) 56 if(isConnected(now,*it)) 57 { 58 // cout<<*it<<' '; 59 que.push(*it),ans[lans]++,dlt.push(*it); 60 } 61 while(!dlt.empty()) 62 { 63 tmp=dlt.front(); dlt.pop(); 64 s.erase(tmp); 65 } 66 } 67 // cout<<endl; 68 // cout<<s.size()<<endl; 69 } 70 } 71 72 int main() 73 { 74 init(); 75 int a,b; 76 scanf("%d%d",&n,&m); 77 for(int i=1;i<=m;i++) 78 { 79 scanf("%d%d",&a,&b); 80 mp[a].push_back(b),mp[b].push_back(a); 81 } 82 for(int i=1;i<=n;i++) 83 sort(mp[i].begin(),mp[i].end()); 84 solve(); 85 sort(ans+1,ans+lans+1); 86 printf("%d\n",lans); 87 for(int i=1;i<=lans;i++) 88 printf("%d ",ans[i]); 89 puts(""); 90 return 0; 91 }