atcoder/CODE FESTIVAL 2017 qual B/B(dfs染色判断是否为二分图)

题目链接:http://code-festival-2017-qualb.contest.atcoder.jp/tasks/code_festival_2017_qualb_c

 

题意:给出一个含 n 个顶点 m 条边的图,对于图中两点 u, v 之间可以添加一条边当且仅当 u, v 是通过三条边连接在一起时,求最多可以添加多少条边.

 

思路:猜结论,当给出的图是二分图时,sol = st1.size() * st2.size() - m,其中 st1.size(), st2.size() 二分图两边的顶点数.

       当给出的图不是二分图时,sol = n * (n - 1) / 2 - m.

 

代码:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const int MAXN=1e5+10;
 6 vector<int> v[MAXN];
 7 vector<int> st1, st2;
 8 bool flag=false;
 9 int vis[MAXN];
10 
11 void dfs(int point){
12     if(flag){
13         return;
14     }
15     for(int i=0; i<v[point].size(); i++){
16         int cnt=v[point][i];
17         if(vis[point]==vis[cnt]){
18             flag=true;
19             return;
20         }else if(!vis[cnt]){
21             if(vis[point]==1){
22                 vis[cnt]=2;
23                 st2.push_back(cnt);
24                 dfs(cnt);
25             }else if(vis[point]==2){
26                 vis[cnt]=1;
27                 st1.push_back(cnt);
28                 dfs(cnt);
29             }
30         }
31     }
32 }
33 
34 int main(void){
35     ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
36     int n, m, x, y;
37     cin >> n >> m;
38     for(int i = 0; i < m; i++){
39         cin >> x >> y;
40         v[x].push_back(y);
41         v[y].push_back(x);
42     }
43     for(int i=1; i<=n; i++){
44         if(v[i].size()==0){
45             continue;
46         }else if(!vis[i]){
47             vis[i]=1;
48             st1.push_back(i);
49             dfs(i);
50         }
51     }
52     ll cnt;
53     if(flag) cnt = (ll)n * (n - 1) / 2 - m;
54     else cnt = (ll)st1.size() * st2.size() - m;
55     cout << cnt << endl;
56     return 0;
57 }
View Code

 

posted @ 2017-10-09 21:04  geloutingyu  阅读(236)  评论(0编辑  收藏  举报