• cf789d 图论计数,自环闭环


    一开始没有思路,以为要判联通块。

    其实不是判断联通块,而是判断边是否连在一起,没有连边的点可以忽略不计

    /*
    分情况讨论:
    1.忽略自环,那么要取出两条相连的普通变作为只经过一次的边 
    2.一条自环,一条普通边
    3.两条自环 
    自环独立存储 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1000005
    #define ll long long
    struct Edge{
        int to,next;
    }edge[maxn<<1];
    int n,m,u,v,head[maxn],tot,vis[maxn],degree[maxn],f[maxn],num1,num2;
    
    void dfs(int u){
        vis[u]=1;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(!vis[v])dfs(v); 
        }
    }
    
    void addedge(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++; 
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof head);
        memset(degree,0,sizeof degree);
        memset(f,0,sizeof f);
        memset(vis,0,sizeof vis);
        tot=num1=num2=0;
        
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            if(v==u)f[u]=1,num1++;
            else {
                addedge(u,v);
                addedge(v,u);
                num2++;
                degree[u]++;
                degree[v]++;
            }
        } 
        
        for(int i=1;i<=n;i++)
            if(degree[i]){//从第一个和其他点有边的点开始 
                dfs(i);break;
            }
        for(int i=1;i<=n;i++)
            if(!vis[i] && (degree[i] || f[i])){
                puts("0");return 0;
            } 
        
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans+=(ll)degree[i]*(degree[i]-1)/2;
        ans+=(ll)num1*num2+(ll)num1*(num1-1)/2;
        printf("%lld
    ",ans); 
    }
  • 相关阅读:
    global s power in php...
    null is empty
    如何创建spring web 工程
    如何下载spring sts
    使用apache-commons-lang3架构对HTML内容进行编码和反编码
    SQL 查询建表SQL
    kindeditor 在JSP 中上传文件的配置
    在java web工程中jsp页面中使用kindeditor
    实现<base>标签中有绝对路径
    实现多个JSP页面共用一个菜单
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10207487.html
Copyright © 2020-2023  润新知