【Educational Codeforces Round 37 E】Connected Components?
阿新 • • 發佈:2018-02-03
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?