codeforces-862B Mahmoud and Ehab and the bipartiteness

题意:给你一颗树,问你最少添加多少边使其能成为二分图。

题解:首先理解一下二分图 https://en.wikipedia.org/wiki/Bipartite_graph。我们观察树,父亲与儿子肯定属于二分图不同的集合,父亲与儿子的儿子肯定属于同一个集合。而且集合的任意一个元素肯定与另一个集合的每个元素有边,如果集合a里元素的个数是aa,集合b里元素的个数是bb,那个边数也就是aa×bb。所以我们可以用dfs对树进行分层,每层和他下下层的属于一个集合,以此类推即可算出答案。或者我们也可以用并差集来统计每个集合的个数。

dfs:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 int n;
 5 vector<int> ve[maxn];
 6 long long num[2];
 7 int vis[maxn];
 8 void dfs(int x,int ss)
 9 {
10     for(int i=0;i<ve[x].size();i++)
11     {
12         if(!vis[ve[x][i]])
13         {
14             num[ss]++;
15             vis[ve[x][i]]=1;
16             dfs(ve[x][i],!ss);
17         }
18     }
19 }
20 void init()
21 {
22     memset(vis,0,sizeof(vis));
23     num[0]=num[1]=0;
24 }
25 int main()
26 {
27     std::ios::sync_with_stdio(false);
28     cin>>n;
29     int s,e;
30     for(int i=0;i<n-1;i++)
31     {
32         cin>>s>>e;
33         ve[s].push_back(e);
34         ve[e].push_back(s);
35     }
36     dfs(1,0);
37     cout<<num[0]*num[1]-(n-1)<<endl;
38 }
原文地址:https://www.cnblogs.com/kearon/p/7695940.html