首页 > 编程语言 >Add Edges to Make Degrees of All Nodes Even

Add Edges to Make Degrees of All Nodes Even

时间:2022-12-18 17:47:20浏览次数:75  
标签:Even 度数 结点 奇数 Make 个数 偶数 Add edges

Add Edges to Make Degrees of All Nodes Even

There is an undirected graph consisting of $n$ nodes numbered from $1$ to $n$. You are given the integer $n$ and a 2D array edges where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi . The graph can be disconnected.

You can add at most two additional edges (possibly none) to this graph so that there are no repeated edges and no self-loops.

Return true if it is possible to make the degree of each node in the graph even, otherwise return false.

The degree of a node is the number of edges connected to it.

Example 1:

Input: n = 5, edges = [[1,2],[2,3],[3,4],[4,2],[1,4],[2,5]]
Output: true
Explanation: The above diagram shows a valid way of adding an edge.
Every node in the resulting graph is connected to an even number of edges.

Example 2:

Input: n = 4, edges = [[1,2],[3,4]]
Output: true
Explanation: The above diagram shows a valid way of adding two edges.

Example 3:

Input: n = 4, edges = [[1,2],[1,3],[1,4]]
Output: false
Explanation: It is not possible to obtain a valid graph with adding at most 2 edges.

Constraints:

$2 \leq \text{edges.length} \leq {10}^{5}$
$\text{edges}[i]\text{.length} \mathrm{==} 2$
$1 \leq a_i, b_i \leq n$
$a_i \ne b_i$
There are no repeated edges.

 

解题思路

  这题就是分类讨论。

  首先容易发现加一条边最多可以将两个度数为奇数的结点变成偶数,又因为最多可以加两条边,因此如果图中度数为奇数的结点个数超过$4$个那么就无解。

  然后如果要加一条边,那么这条边对应的两个结点的度数有$3$种情况:两个都是奇数、两个都是偶数、一个是奇数一个是偶数。

  • 如果给两个度数为奇数的结点连一条边,这两个结点的度数都变成偶数,那么图中度数为奇数的结点的个数就会减少$2$。
  • 如果给两个度数为偶数的结点连一条边,这两个结点的度数都变成奇数,那么图中度数为奇数的结点的个数就会增加$2$。
  • 如果给两个度数奇偶性不同的结点连一条边,这两个结点的度数依然是一个奇数一个偶数,那么图中度数为奇数的结点的个数不变。

  因此可以发现无论怎么连边,图中度数为奇数的结点的个数的奇偶性不会变。又因为最后要保证图中度数为奇数的结点个数为$0$,因此如果图中度数为奇数的结点个数为奇数个,那么无解。事实上度数为奇数的结点个数是奇数这种情况是不可能会发生的。这是因为如果有奇数个度数为奇数的结点,那么把所有结点的度数进行累加后总度数就为奇数,而每条边都与两个结点相连,意味着每条边的度数贡献为$2$,因此总的度数应该为偶数,这就矛盾了。

  因此度数为奇数的结点个数可以分成三种情况:$0$、$2$、$4$。

  对于$0$的情况,直接返回$\text{true}$。

  对于$2$的情况,分连一条边和连两条边的情况。如果要连一条边,那么就应该给这两个结点间连一条边,因为不能有重边,因此只有当这条边不存在才可以连。否则考虑连两条边,在其余的点中找一个点(这个点的度数必然是偶数),然后这个点分别与两个度数为奇数的点连一条边(一样要保证不能有重边)。

  对于$4$的情况,此时必然要把这$4$个度数为奇数的点中分成两组,组内两两连一条边。可以通过枚举全排列或者组合来进行分组,只要存在一种分组情况是可以连边的(无重边),那么就有解。

  AC代码如下:

 1 class Solution {
 2 public:
 3     bool isPossible(int n, vector<vector<int>>& edges) {
 4         vector<int> deg(n + 1);
 5         set<pair<int, int>> st; // 哈希表,统计某条边是否出现过
 6         for (auto &p : edges) {
 7             deg[p[0]]++, deg[p[1]]++;
 8             st.insert({p[0], p[1]}), st.insert({p[1], p[0]});
 9         }
10         vector<int> p;
11         for (int i = 1; i <= n; i++) {
12             if (deg[i] & 1) p.push_back(i); // 找到度数为奇数的点
13         }
14         if (p.size() == 0) {
15             return true;
16         }
17         else if (p.size() == 2) {
18             if (!st.count({p[0], p[1]})) return true;   // 这两个点之间可以连一条边
19             for (int i = 1; i <= n; i++) {  // 找到这两个点之外的点,分别与这两个点连一条边
20                 if (i != p[0] && i != p[1] && !st.count({p[0], i}) && !st.count({p[1], i})) return true;
21             }
22         }
23         else if (p.size() == 4) {
24             do {
25                 if (!st.count({p[0], p[1]}) && !st.count({p[2], p[3]})) return true;    // 组内两点都可以连一条边
26             } while (next_permutation(p.begin(), p.end()));
27         }
28         return false;
29     }
30 };

 

参考资料

  力扣第324场周赛:https://www.bilibili.com/video/BV1wD4y1h7Vz/

标签:Even,度数,结点,奇数,Make,个数,偶数,Add,edges
From: https://www.cnblogs.com/onlyblues/p/16990649.html

相关文章

  • (AtCoder Beginner Contest 282) D - Make Bipartite 2(二分图)
    题目大意:给定一个n个点m条边的图,请你在其中加一条边使得整个图G是二分图,问有多少种可能。(已有的边不能加)解题思路:首先我们要知道,二分图内是没有长度为奇数的回路的所......
  • [ABC282D] Make Bipartite 2 题解
    题目描述给定一个无向简单图\(G\),统计有多少个点对\((u,v)\)满足:\(u,v\)之间没有边直接连接:\((u,v)\notin\textE\)连接\((u,v)\)后\(G\)是二分图......
  • 前端开发系列122-进阶篇之Floating point addition
    title:前端开发系列122-进阶篇之Floatingpointadditiontags:categories:[]date:2019-06-2822:05:13本文简单说明JavaScript中常见的进制转换函数以及浮点数计......
  • 「REMAKE C++」Day 3
    Day3完成了C++Primer第4,5章的阅读常量迭代器,不能修改其所指向的对象,可以移动它,vector<int>::const_iteratorit=v.begin();,常量容器只有常量迭代器。标......
  • yarn add gulp —dev报错
    yarnaddgulp—dev报错这是粪坑里找金针菇的感觉吗?PSE:\Downloads\Compressed\zce-gulp-demo-master>yarnaddgulp--devyarnaddv1.22.19infoNolockfilefoun......
  • D - Make Bipartite 2
    D-MakeBipartite2https://atcoder.jp/contests/abc282/tasks/abc282_d SimpleGraphhttps://mathworld.wolfram.com/SimpleGraph.html Asimplegraph,also......
  • gnu build tools(automake ...) 指导
     ​​http://autotoolset.sourceforge.net/tutorial.html#SEC39​​ ​​http://en.wikipedia.org/wiki/GNU_build_system​​  ​​http://autotoolset.sourceforge.ne......
  • Android添加构建依赖项Add Build Dependencies
    TheGradlebuildsysteminAndroidStudiomakesiteasytoincludeexternalbinariesorotherlibrarymodulestoyourbuildasdependencies.Thedependenciesca......
  • 基于NVIDIA NGC容器安装使用PaddlePaddle
    基于NVIDIANGC容器安装使用PaddlePaddlePaddlePaddlePaddlePaddle作为国内首个自主研发的深度学习平台,自2016年正式向专业社区开源,是一个技术先进、功能丰富,涵盖深度......
  • ubuntu 11.10(32位系统)下编译android源码 make错误解决办法
    本文介绍在ubuntu11.10系统下编译android2.3.3源码,编译之前请确定上两篇文章中所需的准备工作已经成功完成。编译完成生成系统镜像文件,并在模拟器中运行。准备工作完成......