zoukankan      html  css  js  c++  java
  • cf 557D 二分图黑白染色

    题意:给出一个 n 点 m 边的图,问最少加多少边使其能够存在奇环,加最少边的情况数有多少种

    奇环和偶环其实就是二分图的性质:二分图不存在奇环,所以只要判断这张图是否是二分图就行了:

    如果本身就不是二分图,那么说明图中必定有奇环,那就不需要加边,情况数也就是1种了;

    而如果是普通的二分图的话,只要有某一个区块有一半点数大于等于2,那么只要将同一边的任意两点连线,就可以使其不是二分图,从而出现奇环,加边数1条,情况数就是算有多少半点数大于等于2的,从中取两点的情况数;

    如果全部都是两点图的话,就要对某个两点图,将两点同时连向其他任意一点,就需要加2条边,情况数就是两点组数乘剩余点数;

    最后是全部为单点的图,必须连3条线,将任意三点两两相连,情况数就是任取三点的组合数。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 int c[100005];
     8 int n,m,num[2];
     9 int head[100005],nxt[200005],point[200005],size=0;
    10 bool f=0;
    11 
    12 void add(int a,int b){
    13     point[size]=b;
    14     nxt[size]=head[a];
    15     head[a]=size++;
    16     point[size]=a;
    17     nxt[size]=head[b];
    18     head[b]=size++;
    19 }
    20 
    21 void dfs(int a,int x){
    22     if(f)return;
    23     c[a]=x;
    24     num[x]++;
    25     for(int i=head[a];~i;i=nxt[i]){
    26         int b=point[i];
    27         if(c[b]==-1)dfs(b,!x);
    28         else if(c[b]==x){
    29             f=1;
    30             return;
    31         }
    32     }
    33 }
    34 
    35 int main(){
    36     scanf("%d%d",&n,&m);
    37     if(m==0){
    38         ll ans=(ll)n*(ll)(n-1)*(ll)(n-2)/6;
    39         printf("3 %I64d
    ",ans);
    40         return 0;
    41     }
    42     int i;
    43     memset(head,-1,sizeof(head));
    44     memset(c,-1,sizeof(c));
    45     for(i=1;i<=m;i++){
    46         int a,b;
    47         scanf("%d%d",&a,&b);
    48         add(a,b);
    49     }
    50     ll ans=0,ans2=0;
    51     for(i=1;i<=n&&(!f);i++){
    52         if(c[i]==-1){
    53             num[0]=num[1]=0;
    54             dfs(i,1);
    55             ans+=(ll)num[0]*(ll)(num[0]-1)/2;
    56             ans+=(ll)num[1]*(ll)(num[1]-1)/2;
    57             if(num[0]==1&&num[1]==1){
    58                 ans2+=n-2;
    59             }
    60         }
    61     }
    62     if(f)printf("0 1
    ");
    63     else if(ans==0)printf("2 %I64d
    ",ans2);
    64     else printf("1 %I64d
    ",ans);
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    Linux C多线程实现生产者消费者
    数据库视图创建学习
    jsp生成好看的验证码
    每日英语
    ES6学习笔记(一)——let和const
    dataTables的导出Excel功能
    jquery生成二维码图片
    angular2表单初体验
    echarts系列之动态加载数据
    js刷新页面方法
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4676945.html
Copyright © 2011-2022 走看看