首页 > 其他分享 >(AtCoder Beginner Contest 282) D - Make Bipartite 2(二分图)

(AtCoder Beginner Contest 282) D - Make Bipartite 2(二分图)

时间:2022-12-18 16:56:53浏览次数:42  
标签:二分 AtCoder 联通 Beginner Contest int c2 c1 分量

题目大意:

给定一个n个点m条边的图,请你在其中加一条边使得整个图G是二分图,问有多少种可能。(已有的边不能加)


解题思路:

首先我们要知道,二分图内是没有长度为奇数的回路的
所以如果我们将一个图内的点分为两部分,这两部分的点互相连起来的不重复的点都是满足二分图的
例如:
5个点分为两组:[1,2] [3,5]
此时我们所有可以连起来的边为:1-3,1-4,1-5,2-3,2-4,2-5
保证组内的点没有边即保证了没有长度为奇数的回路

我们考虑三种情况:

  1. 当前只有一个联通分量,且该联通分量内本身为一个二分图:
    此时我们只需要染色后得到c1,c2(将图内的点分为两部分),(c1*c2-m)就是答案,表示所有满足二分图的边除去已有的边。
  2. 当前有多个联通分量,且各联通分量内部都为二分图:
    此时我们对其中一个联通分量染色后得到(res1 += (c1*c2))所有可能的边,(res2 += (c1+c2) * (n-(c1+c2)) )当前联通分量可以和其他联通分量之间内连多少条边
    最终我们能够得到res1(所有可能连的边),res2(各联通分量之间连起来的边),但是因为res2在求解的过程中,各联通分量会对同一条边计算两次,所以我们最终的答案为:ans = res1+res2/2-m;
  3. 如果任意联通分量中存在非二分图,那么不论怎么加边都无法保证整个图内没有长度为奇数的回路,所以答案是0

代码实现:

#include<bits/stdc++.h>
using namespace std;
# define int long long
# define endl "\n"
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
vector<int> e[N];
int g[N];
int c1,c2;

bool dfs(int u,int col){//染色+计数
	g[u] = col;
	c1 += col==1;
	c2 += col==2;
	for(auto v:e[u]){
		if(g[v] == g[u]) return false;
		if(!g[v]){
			if(!dfs(v,3-col)) return false;;
		}
	}
	return true;
}
void solve() {
	int n,m;
	cin>>n>>m;
	for(int i = 1;i <= m;++i){
		int a,b;
		cin>>a>>b;
		e[a].push_back(b);
		e[b].push_back(a);
	}
	int res1 = 0,res2 = 0;
	for(int i = 1;i <= n;++i){
		if(!g[i]){
			c1 = c2 = 0;
			if(!dfs(i,1)){//如果存在非二分图,无法加边
				cout<<0<<endl;
				return;
			};
			res1 += c1*c2;
			res2 +=(c1+c2)*(n-c1-c2);
		}
	}
	int ans = res1+res2/2-m;//第一二种情况合并起来,因为如果只有一个联通分量,res2为0
	cout<<ans<<endl;

}
int tt;
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	tt = 1;
//	cin >> tt;
	while (tt--) solve();


	return 0;
}

标签:二分,AtCoder,联通,Beginner,Contest,int,c2,c1,分量
From: https://www.cnblogs.com/empty-y/p/16990544.html

相关文章

  • atcoder ABC 282(A-C)
    A输入k,要从A打印到第k个大写字母。只要看懂题目就行。#include<iostream>usingnamespacestd;intmain(){ intk; scanf("%d",&k); for(inti=0;i<k;i++){ prin......
  • AtCoder Beginner Contest 282
    A-GeneralizedABC(abc282a)题目大意给定\(n\),输出一个字符串,从'A','B','C'...拼接得到的长度为\(n\)。解题思路模拟即可。神奇的代码#include<bits/stdc++.h......
  • AtCoder Beginner Contest 281 (A-D)
    A题意:输入一个整数,输出(n+1)行,从n一直输出到0.解法/思路:一个循环完事儿。代码:#include<iostream>usingnamespacestd;intmain(){ intn; cin>>n; for(in......
  • AtCoder Beginner Contest 280 (A-D)
    本人第一次写博客,若有不足还望指出(•̀ω•́)✧A题意:输入一个H行W列的字符矩阵,统计'#'的个数。解法/思路:挺简单的,直接贴代码吧。代码:#include<iostream>#incl......
  • HHKB Programming Contest 2022 Winter(AtCoder Beginner Contest 282)
    前言好久没有打AtCoder了。有点手生。只拿到了\(\operatorname{rk}1510\),应该上不了多少分。只切了\(\texttt{A,B,C,D}\)四题。A-GeneralizedABC简要题意给出......
  • 「Editorial」Codeforces Contest 1149
    C.TreeGenerator™容易发现树上一条路径一定形如))...)((...(。也就是对于任意子段,去掉匹配了的括号后还剩下的部分。而这个东西还是不太好表示,我们有如下引理:这个值......
  • AtCoder Regular Contest 143 E Reversi
    AtCoder传送门洛谷传送门翻转一个点会把它相邻的点全部翻转,因此先从叶子开始自下而上考虑。不难发现,如果这个叶子是白色,那么它一定比它的父亲先翻转(否则它就翻不了了);而......
  • AtCoder Regular Contest 150 F Constant Sum Subsequence
    AtCoder传送门洛谷传送门定义\(\mathrm{nxt}(i,x)\)为最小的\(j\)满足\(a_j=x\)且\(j>i\),\(\mathrm{pre}(i,x)\)为最大的\(j\)满足\(a_j=x\)且\(j<......
  • atcoder beginner 281 DEFG 题解
    比赛链接:https://atcoder.jp/contests/abc281题解:D\(dp[i][j][k]\)表示考虑到第i个数,集合加入了\(k\)个数,余数为\(j\)的答案转移即可//bySkyRainWind#inclu......
  • gym104090 The 2022 ICPC Asia Hangzhou Regional Programming Contest I. Guess Cycl
    题目大意交互题给出一个长度为n的排列p,初始有一个人在某个位置(未知)每次询问可以给出一个步数x,然后人会向前走x步并返回所在位置的数字在1e4次询问内找到n,n<=1e9保证排......