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 }