zoukankan      html  css  js  c++  java
  • LOJ #2877. 「JOISC 2014 Day2」交朋友 并查集+BFS

    这种图论问题都挺考验小思维的.   

    首先,我们把从 $x$ 连出去两条边的都合并了.  

    然后再去合并从 $x$ 连出去一条原有边与一条新边的情况.  

    第一种情况直接枚举就行,第二种情况来一个多源 bfs 即可. 

    code:

    #include <cstdio> 
    #include <string>
    #include <vector>
    #include <queue>      
    #include <algorithm>
    #define N 100006    
    #define ll long long 
    using namespace std; 
    namespace IO 
    {   
        inline void setIO(string s) 
        {
            string in=s+".in"; 
            string out=s+".out"; 
            freopen(in.c_str(),"r",stdin);  
            // freopen(out.c_str(),"w",stdout);  
        }
    };              
    int edges;     
    queue<int>q;    
    vector<int>G[N];    
    int size[N],p[N],out[N],vis[N];          
    inline void add(int u,int v) { G[u].push_back(v); }   
    inline int find(int x)   { return p[x]==x?x:p[x]=find(p[x]); }   
    inline void initialize() { for(int i=0;i<N;++i) size[i]=1,p[i]=i; }
    int main() 
    {
        // IO::setIO("input");  
        int i,j,n,m;      
        initialize();  
        scanf("%d%d",&n,&m);                        
        for(i=1;i<=m;++i) 
        {
            int x,y;  
            scanf("%d%d",&x,&y),++out[x],add(x,y);  
        }   
        for(i=1;i<=n;++i) 
        {   
            for(j=1;j<G[i].size();++j) 
            {
                int pr=G[i][j-1],cur=G[i][j];     
                if(find(pr)!=find(cur)) 
                {
                    pr=find(pr),cur=find(cur);   
                    p[pr]=cur,size[cur]+=size[pr];   
                }
            }
        }                                  
        for(i=1;i<=n;++i) 
        {
            int x=find(i);   
            if(size[x]>1) q.push(i),vis[i]=1;      
        }
        while(!q.empty()) 
        {
            int u=q.front(); q.pop();          
            for(i=0;i<G[u].size();++i) 
            {
                int v=G[u][i];    
                if(find(v)!=find(u)) 
                {
                    int a=find(u),b=find(v);     
                    p[a]=b,size[b]+=size[a];           
                }
                if(!vis[v]) q.push(v),vis[v]=1;   
            }    
        }   
        ll ans=0;  
        for(i=1;i<=n;++i) 
        { 
            if(p[i]==i) 
                ans+=(size[i]>1?(ll)(size[i]-1)*size[i]:out[i]);     
        }
        printf("%lld
    ",ans);    
        return 0;  
    }
    

      

  • 相关阅读:
    如何使用 systemctl 管理服务
    Linux 下 SVN 的安装和配置
    C语言程序设计
    mysql 常用关键字操作(字符串转数字,字符串截取)
    Spring入门学习---05
    Spring入门学习---03
    使用 TiUP 部署 TiDB 集群
    docker安装kafka+kafka-manager集群
    发发牢骚
    php修改JPG格式图片的dpi
  • 原文地址:https://www.cnblogs.com/guangheli/p/12378108.html
Copyright © 2011-2022 走看看