zoukankan      html  css  js  c++  java
  • codeforces 557D Vitaly and Cycle

    题意简述

    给定一个图 求至少添加多少条边使得它存在奇环 并求出添加的方案数

    (注意不考虑自环)

    -----------------------------------------------------------------------------

    一道二分图染色的讨论题

    比赛时只会用二分图染色判断树以及偶环 忘记用这个来判奇环。。。

    二分图染色这种联赛知识点的题目现在也不会写了。。。

    ------------------------------------------------------------------------------

    我们可以按需要添加边的条数来讨论这题

    首先讨论添加边条数为3——即原原图边数m为0时

    $ans=n*(n-1)*(n-2)/6$

    再讨论添加边条数为2——即原图中所有边都没有公共端点/所有点度数<=1 时

    $ans=m*(n-2)$

    再讨论添加边数为0——即原图中存在奇环时

    $ans=1$

    最后讨论添加边数为1——即原图中只有树以及偶环

    $ans=sum(white[i]-1)*white[i]/2+(black[i]-1)*black[i]/2$

    其实思路清晰后实现起来就很容易了

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define rep(i,n) for(int i=1;i<=n;++i)
    #define imax(x,y) (x>y?x:y)
    #define imin(x,y) (x<y?x:y)
    using namespace std;
    const int N=100010;
    int firste[N],nexte[N<<1],v[N<<1];
    int color[N],fa[N],bl[N],wh[N],degree[N];
    int n,m,e=1,flag=1;
    long long ans=0;
    void build_edge(int x,int y)
    {
        ++e;
        nexte[e]=firste[x];
        firste[x]=e;
        v[e]=y;
    }
    void dfs(int u,int c,int f)
    {
        color[u]=c;
        fa[u]=f;
        if(c&1)++bl[f];
        else ++wh[f];
        for(int p=firste[u];p;p=nexte[p])
            if(!color[v[p]])dfs(v[p],3-c,f);
        else if(color[v[p]]==color[u])
        {
            flag=1;
            return;
        }
    }
    int main()
    {
        int x,y;
        scanf("%d%d",&n,&m);
        if(!m)
        {
            ans=(long long)n*(n-1)*(n-2)/6;
            printf("3 %I64d",ans);
            return 0;
        }
        rep(i,m)
        {
            scanf("%d%d",&x,&y);
            build_edge(x,y);
            build_edge(y,x);
            ++degree[x];
            ++degree[y];
            if(degree[x]>1||degree[y]>1)flag=0;
        }
        if(flag)
        {
            ans=(long long)m*(n-2);
            printf("2 %I64d",ans);
            return 0;
        }
        int cnt=0;
        rep(i,n)
        if(!color[i])
        {
            dfs(i,1,++cnt);
            if(flag)
            {
                printf("0 1");
                return 0;
            }
        }
        rep(i,cnt)
        ans+=(long long)(wh[i]-1)*wh[i]/2+(long long)(bl[i]-1)*bl[i]/2;
        printf("1 %I64d",ans);
        return 0;
    }
  • 相关阅读:
    并发和并行的区别
    fiddler-打断点(bpu)
    fiddler操作
    fiddler手机抓包
    面试题1
    Linux查看日志常用命令
    HTMLTestRunner
    mysql数据库无法插入特殊字符报错
    mybatis解决属性名和数据库字段名不一致问题
    Vue路由的使用简单实例
  • 原文地址:https://www.cnblogs.com/sagitta/p/4612214.html
Copyright © 2011-2022 走看看