• 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;  
    }
    

      

  • 相关阅读:
    webstorm
    web大文件上传(web应用---SSH框架)
    Webuploader 大文件分片上传
    百度Webuploader 大文件分片上传(.net接收)
    java使用WebUploader做大文件的分块和断点续传
    大文件上传插件webupload插件
    使用Webuploader大文件分片传输
    使用原生Java Web来实现大文件的上传
    Java实现浏览器端大文件分片上传
    怎样使用word2013发布csdn博客
  • 原文地址:https://www.cnblogs.com/guangheli/p/12378108.html
Copyright © 2020-2023  润新知