CodeForces 862B Mahmoud and Ehab and the bipartiteness(二分图)

B. Mahmoud and Ehab and the bipartiteness
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mahmoud and Ehab continue their adventures! As everybody in the evil land knows, Dr. Evil likes bipartite graphs, especially trees.

A tree is a connected acyclic graph. A bipartite graph is a graph, whose vertices can be partitioned into 2 sets in such a way, that for each edge (u, v) that belongs to the graph, u and v belong to different sets. You can find more formal definitions of a tree and a bipartite graph in the notes section below.

Dr. Evil gave Mahmoud and Ehab a tree consisting of n nodes and asked them to add edges to it in such a way, that the graph is still bipartite. Besides, after adding these edges the graph should be simple (doesn't contain loops or multiple edges). What is the maximum number of edges they can add?

A loop is an edge, which connects a node with itself. Graph doesn't contain multiple edges when for each pair of nodes there is no more than one edge between them. A cycle and a loop aren't the same .

Input

The first line of input contains an integer n — the number of nodes in the tree (1 ≤ n ≤ 105).

The next n - 1 lines contain integers u and v (1 ≤ u, v ≤ nu ≠ v) — the description of the edges of the tree.

It's guaranteed that the given graph is a tree.

Output

Output one integer — the maximum number of edges that Mahmoud and Ehab can add to the tree while fulfilling the conditions.

Examples
input
Copy
3
1 2
1 3
output
0
input
Copy
5
1 2
2 3
3 4
4 5
output
2
Note

Tree definition: https://en.wikipedia.org/wiki/Tree_(graph_theory)

Bipartite graph definition: https://en.wikipedia.org/wiki/Bipartite_graph

In the first test case the only edge that can be added in such a way, that graph won't contain loops or multiple edges is (2, 3), but adding this edge will make the graph non-bipartite so the answer is 0.

In the second test case Mahmoud and Ehab can add edges (1, 4) and (2, 5).

一直在纠结cycle和loop,想了半天才看到题面有说。其实就是个二分图,问你能加多少不产生自环和多重边的边。就染个色算出来两边各多少个结点,然后把没连上的点都连上就是了。

[cpp]  view plain  copy
  1. #include <bits/stdc++.h>  
  2. #include <cstring>  
  3. using namespace std;  
  4. vector <int>edge[100005];  
  5. int vis[100005];  
  6.   
  7. int main()  
  8. {  
  9.     int n;  
  10.     scanf("%d",&n);  
  11.     int a,b;  
  12.     for(int i=1;i<n;i++)  
  13.     {  
  14.         scanf("%d%d",&a,&b);  
  15.         edge[a].push_back(b);  
  16.         edge[b].push_back(a);  
  17.     }  
  18.     long long num=1;  
  19.     vis[1]=1;  
  20.     queue<int> que;  
  21.     que.push(1);  
  22.     while(!que.empty())  
  23.     {  
  24.         int now=que.front();  
  25.         que.pop();  
  26.         for(int i=0;i<edge[now].size();i++)  
  27.         {  
  28.             if(vis[edge[now][i]]==0)  
  29.             {  
  30.                 que.push(edge[now][i]);  
  31.                 if(vis[now]==1)  
  32.                     vis[edge[now][i]]=2;  
  33.                 else  
  34.                 {  
  35.                     vis[edge[now][i]]=1;  
  36.                     num++;  
  37.                 }  
  38.             }  
  39.         }  
  40.     }  
  41.     //cout<<num<<endl;  
  42.     long long ans=0;  
  43.     for(int i=1;i<=n;i++)  
  44.     {  
  45.         if(vis[i]==2)  
  46.             ans+=num-edge[i].size();  
  47.         else  
  48.             ans+=n-num-edge[i].size();  
  49.     }  
  50.     cout<<ans/2<<endl;  
  51.     return 0;  
  52. }  
### Codeforces 平台上的二分图染色算法题目 #### CF1949I. Disks 的解题思路 对于给定的一组圆盘,判断是否存在一种方式使得这些圆盘能够通过改变大小来满足特定条件。如果存在某个圆既变小又变大,或者变小的圆的数量不等于变大的圆的数量,则该连通块无法实现目标状态[^5]。 为了验证这一点,可以采用二分图染色的方法: - 将每个圆视为图中的节点; - 如果两个圆之间有交集,则在这两个节点间建立一条边; - 使用两种不同的颜色尝试对整个图形进行着色,在此过程中遇到冲突则说明不存在合法方案; 这种方法不仅适用于本题描述的情况,也广泛应用于其他涉及二分性质的问题求解中。 #### 构造性算法实例 在解决一些具有构造特性的编程挑战时,比如构建IP地址这样的任务[T1 IP地址(ip)][^2],虽然这并不是典型的二分图问题,但是当涉及到如何有效地分配资源(如同一网络内的设备编号),也可以借鉴类似的思维模式——即合理规划不同部分之间的关系以达到最优配置效果。 ```cpp // C++ code snippet demonstrating bipartite graph coloring approach #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 7; int color[MAXN]; vector<int> adj[MAXN]; bool dfs(int u, int c) { color[u] = c; for (auto v : adj[u]) { if (!color[v]) { if (!dfs(v, 3 - c)) return false; // alternate colors between 1 and 2 } else if (color[v] == c) return false; // found an odd cycle or conflict } return true; } void solve() { memset(color, 0, sizeof(color)); bool isBipartite = true; for (int i = 1; i <= n && isBipartite; ++i) { if (!color[i]) isBipartite &= dfs(i, 1); } cout << (isBipartite ? "YES\n" : "NO\n"); } ``` 上述代码展示了利用深度优先搜索(DFS)来进行二分图检测的过程。这里假设输入已经准备好了一个无向图的数据结构`adj[]`表示邻接表形式存储的图以及顶点数量n。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值