题目大意:给定一个连通图,如果(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 }