zoukankan      html  css  js  c++  java
  • 洛谷 [POI2007]BIU-Offices 解题报告

    [POI2007]BIU-Offices

    题意

    给定(n(le 100000))个点(m(le 2000000))条边的无向图(G),求这个图(G)补图的连通块个数。


    一开始想了半天各种啥啥啥优化补图连边。

    但复杂度没算好,最开始( t{set})的想法是可以通过此题的。

    使用链表+队列可以做到(O(n+m))的复杂度

    具体流程如下:

    1. 将所有的点加入链表
    2. 从链表中随便拿出一个点加入队列,如果链表为空,结束
    3. 遍历队列
      • 对于当前点,把( t{Ta})的连接的边打标记。
      • 遍历链表,取出没有打标记的点从链表中删去并加入队列。
      • 取消标记。
    4. (3)中进入队列的点统计为一个连通块

    考虑这样的复杂度为什么是(O(n+m))

    每条边两边的点会被打一次标记并取消一次标记,并最多一次作为遍历链表时没有被删去的点,这里是(O(m))的。

    每个点最多会从链表中删去一次,这里是(O(n))的。


    Code:

    #include <cstdio>
    #include <algorithm>
    const int N=1e5+10;
    const int M=2e6+10;
    int head[N],to[M<<1],Next[M<<1],cnt;
    void add(int u,int v)
    {
        to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
    }
    int n,m,pre[N],suc[N],q[N],l,r,ans[N],col[N],tot;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int u,v,i=1;i<=m;i++)
            scanf("%d%d",&u,&v),add(u,v),add(v,u);
        for(int i=1;i<=n;i++)
            pre[i]=i-1,suc[i]=i+1;
        suc[0]=1,suc[n]=0;
        while(suc[0])
        {
            l=1,r=0;
            q[++r]=suc[0];
            suc[0]=suc[suc[0]];
            pre[suc[q[r]]]=0;
            while(l<=r)
            {
                int now=q[l++];
                for(int i=head[now];i;i=Next[i])
                    col[to[i]]=1;
                int cur=suc[0];
                while(cur)
                {
                    if(!col[cur])
                    {
                        q[++r]=cur;
                        pre[suc[cur]]=pre[cur];
                        suc[pre[cur]]=suc[cur];
                    }
                    cur=suc[cur];
                }
                for(int i=head[now];i;i=Next[i])
                    col[to[i]]=0;
            }
            ans[++tot]=l-1;
        }
        std::sort(ans+1,ans+1+tot);
        printf("%d
    ",tot);
        for(int i=1;i<=tot;i++) printf("%d ",ans[i]);
        return 0;
    }
    

    2018.11.8

  • 相关阅读:
    网站如何做分布式(集群)的大纲
    [转]Bind和Eval的区别详解
    SQL 中游标的并发问题。
    如何利用客户端缓存对网站进行优化?
    Windows的第五种群集方案 CCS
    ICollection 接口的类序列化的问题。
    如何提高网页的效率(上篇)——提高网页效率的14条准则
    石油地质名称解释
    【SQL基础概念】
    DataView/DataRowView
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9929606.html
Copyright © 2011-2022 走看看