Atcoder Code Festival Qual B C题 3step

题目大意:给定一个连通图,如果(u,v)点集,存在一条经过三条不重复边的路径连接u,v,则可以连接u,v一条边,问最多能连多少边。

题目分析:考虑新增加一条边的影响,不难发现,会影响全图的所有点,所以要从最终形成的图的性质考虑。

如果原图是个二分图,则新增的边只会在两个点集之间,而且会成为完全二分图。

如果原图不是二分图,则整个图是一个集合,所以会变成一个完全图。

注意:爆int

 1 #include<bits/stdc++.h>
 2 #define LL long long 
 3 #define maxn 100010
 4 #define pb push_back
 5 using namespace std;
 6 vector<int> G[maxn];
 7 LL d[maxn],a[maxn],b[maxn],n,m, p, q;
 8 bool vis[maxn];
 9 void dfs(int x,int fa){
10     int now;
11     d[x] = (d[fa] + 1) % 2;
12     vis[x] = true;
13     for(int i = 0; i < G[x].size(); i ++){
14         now = G[x][i];
15         if(!vis[now]){
16             dfs(now,x);
17         }
18     }
19 }
20 int main(){
21     cin >> n >> m;
22     if(n <= 3){
23         cout << 0;
24         return 0;
25     }
26     for(int i = 1; i <= m; i ++){
27         cin >> a[i] >> b[i];
28         G[a[i]].pb(b[i]);
29         G[b[i]].pb(a[i]);
30     }
31     dfs(1,0);
32     bool flag = true;
33     for(int i = 1; i <= n; i ++){
34         if(d[i] == 0) p ++;
35         else q ++;
36     }
37     for(int i = 1; i <= m; i ++){
38         if(d[a[i]] == d[b[i]]){
39             flag = false;
40             break;
41         }
42     }
43     if(!flag)    cout << n * (n - 1) / 2 - m;
44     else    cout << p * q - m;
45     return 0;
46 }
原文地址:https://www.cnblogs.com/poler/p/7641091.html