[cf557d]Vitaly and Cycle(黑白染色求奇环)

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

解题关键:黑白染色求奇环,利用数量分析求解。

奇环:含有奇数个点的环。

二分图不存在奇环。反之亦成立。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int maxm=1e5+5;

int c[maxn];       //color,每个点的黑白属性,-1表示还没有标记,0/1表示黑白,比vis数组多一个作用
ll num[2];        //在一次DFS中的黑白点个数
bool f=0;          //判断是否出现奇环

int head[maxn],tot,n,m,a,b;
struct edge{
    int to;
    int nxt;
}e[maxm];
void add_edge(int u,int v){
    e[tot].to=v;
    e[tot].nxt=head[u];
    head[u]=tot++;
}
void init(){
    memset(head,-1,sizeof head);
    tot=0;
    memset(c,-1,sizeof c);
}

void dfs(int u,int x){
    if(f)return;
    c[u]=x;
    num[x]++;
    for(int i=head[u];~i;i=e[i].nxt){
        int j=e[i].to;
        if(c[j]==-1) dfs(j,!x);
        else if(c[j]==x){//存在奇环
            f=1;
            return;
        }
    }
}
int main(){
    init();
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>a>>b;
        add_edge(a,b);
        add_edge(b,a);
    }
    ll ans=0,ans2=0;
    if(m==0){
        ans=(ll)n*(n-1)*(n-2)/6;
        printf("3 %lld\n",ans);
        return 0;
    }
    for(int i=1;i<=n&&(!f);i++){
        if(c[i]==-1){
            num[0]=num[1]=0;
            dfs(i,1);
            ans+=(num[0]*(num[0]-1)+num[1]*(num[1]-1))/2;
            if(num[0]==1&&num[1]==1){
                ans2+=n-2;
            }
        }
    }
    if(f) printf("0 1\n");
    else if(ans) printf("1 %lld\n",ans);
    else printf("2 %lld\n",ans2);
    return 0;
}

原文地址:https://www.cnblogs.com/elpsycongroo/p/10356827.html

时间: 2024-10-08 11:35:45

[cf557d]Vitaly and Cycle(黑白染色求奇环)的相关文章

【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 11661   Accepted: 3824 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, an

Codeforces Round #311 (Div. 2) D. Vitaly and Cycle(二分图染色,奇环)

给定n个点,m条边. 求最少最要加几条边使图中存在奇环,且输出此时加边的方法种数 根据题意,只可能为 0:已经存在奇环,dfs搜到已经染色的且颜色相同 1:判断每个连通块里的 染色黑白色的个数 2 :某个点的 度 > 1 3:0条边 1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<vector> 5 #include<stack> 6 #include

fzu2181(点的双连通分量+求奇环)

求出每个点双连通分量,如果在一个点双连通分量中有奇环,则这个分量每个点都在一个奇环中.  关键是要知道怎么求点双连通分量以及点双连通的性质. fzu2181 http://acm.fzu.edu.cn/problem.php?pid=2181 #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define

Hdu 5285 wyh2000 and pupil (bfs染色判断奇环) (二分图匹配)

题目链接: BestCoder Round #48 ($) 1002 题目描述: n个小朋友要被分成两班,但是有些小朋友之间是不认得的,所以规定不能把不认识的小朋友分在一个班级里面,并且一班的人数要比二班的人数多,每个班的人数都大于零. 解题思路: hdu给出的题解是二分图匹配加上贪心,就不多说了. 还可以用bfs对节点染色,建好图后,对节点进行bfs分成,偶数成与奇数成染成不同的颜色,颜色相同的节点都可以分到同一个集合里面,但是要判断一下奇环,如果出现奇环的话,是无法进行分组的.在每次bfs的

(01 染色判奇环) hdu 3478

Catch Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1296    Accepted Submission(s): 632 Problem Description A thief is running away!We can consider the city where he locates as an undirected g

HDU 1565 (最大流+黑白染色化二分图求最小割)

http://acm.hdu.edu.cn/showproblem.php?pid=1565 思路:将横纵坐标和为偶尔染白色,其他染黑色,黑点连接源点,流量为该点的值,白点连接汇点,流量为该点的值,黑白点有相邻的就连边,值为无穷大.最后求最大流,即该图的最小割. PS:刚开始不明白为为什么最大流会等于最小割,为什么所有的点之和减去最小割就会等于答案. 我的理解是:整张图其实就跟连接管道一样,连接了黑点表示取了黑点那个值的流量,白点也是,而连接了相邻的黑白点求出的最大流就会是流量较小的那个的值.好

POJ 1466 Girls and Boys 黑白染色 + 二分匹配 (最大独立集) 好题

有n个人, 其中有男生和女生,接着有n行,分别给出了每一个人暗恋的对象(不止暗恋一个) 现在要从这n个人中找出一个最大集合,满足这个集合中的任意2个人,都没有暗恋这种关系. 输出集合的元素个数. 刚开始想,把人看成顶点,若有暗恋的关系,就连一条边,构成一个图 独立集的概念:一个图中两两互不相连的顶点集合 所以这道题,就是要求最大独立集 有:最大独立集+最小顶点覆盖=|V|(顶点的总个数) 那就求最小顶点覆盖了 根据题意: 暗恋的对象性别不同,所以a暗恋b,b暗恋c,c暗恋a这种关系不可能存在 也

Catch---hdu3478(染色法判断是否含有奇环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 题意:有n个路口,m条街,一小偷某一时刻从路口 s 开始逃跑,下一时刻都跑沿着街跑到另一路口,问是否存在某一时刻出,小偷可能出现在任意路口: 如果小偷能走一个环,如果这个环是偶数个节点,那么某个节点只能在偶数时刻或者奇数时刻到达: 但是如果这个环是奇数个节点,他既可以在奇数时刻到达又可以在偶数时刻到达:所以这道题就是求是否存在一个奇环:如果存在输出YES,否则NO: 由于二分图中不能含有奇环,

hdu 5285 二分图黑白染色

题意:给出 n 个人,以及 m 对互不认识的关系,剩余的人都互相认识,要将所有人分成两组,组内不能有互不认识的人,要求每组至少有一人,并且第一组人数尽量多,问两组人数或不可能时单独输出 BC 48 场的B题,这两天黑白染色做的不少,要把互不认识的人分在不同的组里,其实就是看整个图是否能够形成二分图,如果不能形成二分图的话,那么说明图中一定存在奇环,那么人就不能分在两个组中而保证组内都认识.所以就是判二分图,用黑白染色,然后将染色后数量多的点分在第一组,剩余分在第二组.但是题中有坑点,首先,人数小