1. 程式人生 > >【Educational Codeforces Round 37 E】Connected Components?

【Educational Codeforces Round 37 E】Connected Components?

com 很快 之間 include mar while 它的 所有 conn

【鏈接】 我是鏈接,點我呀:)
【題意】


在這裏輸入題意

【題解】


bfs.
用一個鏈表來記錄哪些點已經確定在某一個聯通快裏了。
一開始每個點都能用。
然後從第一個點開始進行bfs.
然後對於它的所有連接著的點(輸入的圖的補圖
看看它是不是之前進行過bfs,如果是的話。就跳過。(可以用鏈表直接跳過。即沿著鏈表枚舉它的出度。
否則。把這個點從鏈表中刪掉。然後把這個點加入隊列。繼續bfs即可。
這樣已經確定聯通了的點之間不會再訪問。
鏈表加速了尋找某個點的出度的過程。
且由於當n很大的時候。m只有200000
因此可以很快地進入某個點的bfs.所以鏈表的刪除速度會很快。

【代碼】

#include<bits/stdc++.h>
using namespace std; const int N = 2e5; int n,m; vector<int> g[N+10]; int nex[N+10],bef[N+10],ban[N+10]; bool _deleted[N+10]; queue<int> dl; vector<int> ans; void _delete(int x){ _deleted[x] = 1; int y = bef[x],z = nex[x]; nex[y] = z; bef[z] = y; } void bfs(int x){ ans.push_back(1
); _delete(x); dl.push(x); while (!dl.empty()){ int x = dl.front(); dl.pop(); for (int y:g[x]) ban[y] = 1; for (int i = nex[0];i!=n+1;i=nex[i]){ if (ban[i]) continue; _delete(i); dl.push(i); ans.back()++; } for
(int y:g[x]) ban[y] = 0; } } int main() { cin >> n >> m; for (int i = 1;i <= m;i++){ int x,y; cin >> x >> y; g[x].push_back(y); g[y].push_back(x); } for (int i = 0;i <= n+1;i++) nex[i] = i+1,bef[i] = i-1; for (int i = 1;i != n+1;i=nex[i]){ if (_deleted[i]) continue; bfs(i); } cout<<(int)ans.size()<<endl; sort(ans.begin(),ans.end()); for (int x:ans) cout<<x<<' '; return 0; }

【Educational Codeforces Round 37 E】Connected Components?