首页 > 其他分享 >AtCoder Beginner Contest 282

AtCoder Beginner Contest 282

时间:2022-12-18 21:01:29浏览次数:75  
标签:二分 AtCoder 连通 Beginner PII int res 282 分量

《Make Bipartite 2》

思维,二分图

 

 这个简单图可以有两种情况:

  1.全部点都通过边连起来,即连通分量只有一个,其自己

  2.还有有些点没有全部连起来,即有多个连通分量

1.不管上面哪一种情况,如果对图跑一个二分图染色O(n+m),如果染色失败,则都是返回0,因为这时,不管再连上那一边都不是二分图了

 

下面我们保证跑一个二分图染色O(n+m),如果染色成功:

2.现在我们假设各个点之间都有边,即一共有n*(n-1)/2条边

    (1)对于只有一个连通分量来说: 连上相同颜色的点的边和已经连好的边(m),都是使二分图不合法的,除此之外都是合法的

  则假设这个连通分量上有w个白点,b个黑点,则不合法的边为 w*(w-1)/2+b*(b-1)/2+m条

  则正确答案为ans=n*(n-1)/2-(w*(w-1)/2+b*(b-1)/2+m);

    (2)对于有多个连通分量来说:两个不同的连通分量上的任意点相连,都还是二分图

  对于相同连通分量上的相同颜色的点相连是不合法的,同时已经连好的边(m)也是不合法的

于是:

 

 这里循环相加的是各个连通分量上黑点相连的边数与白点相连的边数

 

即我们在写dfs跑二分图染色时,可以返回这个连通分量上黑点与白点的个数

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 const int N = 2 * 1e5 + 2;
 7 typedef long long ll;
 8 typedef pair<int, int> PII;
 9 int color[N], n, m;
10 vector<int> sides[N];
11 PII dfs(int x, int c)
12 {
13     PII p = {0, 0};
14     color[x] = c;
15     if (c == 1)
16         p.first++;
17     else
18         p.second++;
19     for (int i = 0; i < sides[x].size(); i++)
20     {
21         int j = sides[x][i];
22         PII res;
23         if (!color[j])
24             res = dfs(j, -c);
25         else if (color[j] == c)
26             // 表示不构成二分图
27             return {-1, -1};
28         if (res.first == -1 && res.second == -1)
29             return {-1, -1};
30         else
31         {
32             p.first += res.first;
33             p.second += res.second;
34         }
35     }
36     return p;
37 }
38 int main()
39 {
40     cin >> n >> m;
41     for (int i = 1; i <= m; i++)
42     {
43         int a, b;
44         scanf("%d%d", &a, &b);
45         sides[a].push_back(b), sides[b].push_back(a);
46     }
47     ll ans = (ll)n * (n - 1) / 2 - m;
48     for (int i = 1; i <= n; i++)
49     {
50         if (!color[i])
51         {
52             PII p = dfs(i, 1);
53             // p.first表示这个连通分量中染色白色的个数(color==1),p.second 表示这个连通分量中染色黑色的个数;
54             if (p.first == -1 && p.second == -1)
55             {
56                 cout << 0;
57                 return 0;
58             }
59             ans -= (ll)p.first * (p.first - 1) / 2;
60             ans -= (ll)p.second * (p.second - 1) / 2;
61         }
62     }
63     cout << ans;
64     return 0;
65 }

 

标签:二分,AtCoder,连通,Beginner,PII,int,res,282,分量
From: https://www.cnblogs.com/cilinmengye/p/16990902.html

相关文章

  • (AtCoder Beginner Contest 282) D - Make Bipartite 2(二分图)
    题目大意:给定一个n个点m条边的图,请你在其中加一条边使得整个图G是二分图,问有多少种可能。(已有的边不能加)解题思路:首先我们要知道,二分图内是没有长度为奇数的回路的所......
  • 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......
  • [ABC282D] Make Bipartite 2 题解
    题目描述给定一个无向简单图\(G\),统计有多少个点对\((u,v)\)满足:\(u,v\)之间没有边直接连接:\((u,v)\notin\textE\)连接\((u,v)\)后\(G\)是二分图......
  • 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简要题意给出......
  • 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......