[POI 2007] 办公楼

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1098

[算法]

        显然 , 答案为补图的连通分量个数

        用链表优化BFS , 时间复杂度 : O(N + M)

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define MAXM 2000010

struct edge
{
        int to , nxt;
} e[MAXM << 1];

int n , m , tot , cnt;
int head[MAXN] , ans[MAXN] , L[MAXN] , R[MAXN];
bool visited[MAXN] , mark[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedge(int u , int v)
{
        ++tot;
        e[tot] = (edge){v , head[u]};
        head[u] = tot;
}
inline void del(int x)
{
        R[L[x]] = R[x];
        L[R[x]] = L[x];
}
inline void bfs(int s)
{
        queue< int > q;        
        visited[s] = true;
        q.push(s);
        while (!q.empty())
        {
                int cur = q.front();
                q.pop();
                ++ans[cnt];
                for (int i = head[cur]; i; i = e[i].nxt)
                {
                        int v = e[i].to;
                        mark[v] = true;
                }
                for (int i = R[0]; i; i = R[i]) 
                {
                        if (!mark[i] && !visited[i])
                        {
                                visited[i] = true;
                                del(i);
                                q.push(i);
                        }
                }
                for (int i = head[cur]; i; i = e[i].nxt)
                {
                        int v = e[i].to;
                        mark[v] = false;
                }
        }
}

int main()
{
        
        read(n); read(m);
        for (int i = 1; i <= m; i++)
        {
                int u , v;
                read(u); read(v);
                addedge(u , v);
                addedge(v , u);
        }
        for (int i = 0; i <= n; i++) L[i] = i - 1 , R[i] = i + 1;
        R[n] = 0;
        for (int i = 1; i <= n; i++)
        {
                if (!visited[i])
                {
                        ++cnt;
                        bfs(i);        
                }        
        }
        printf("%d\n" , cnt);
        sort(ans + 1 , ans + cnt + 1);
        for (int i = 1; i <= cnt; i++) printf("%d " , ans[i]);
        printf("\n");
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9926142.html