给你一个n个点m条边的无向图,进行以下操作 如果存在两个点u和v,使得从u走三步能恰好到达v,那么在u和v之间连接一条边
重复这个操作直到不能再连接新的边,问最后有多少条边?
n, m <= 100000

如果一个连通块包含奇环它一定会变成完全图

如果一个连通块没有奇环,那么它一定是二分图,二分图一定会变成“完全二分图”

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;
vector <int> g[N];
int n,m,c[N],ans,s1,s2,vis[N],flag,tot;

void dfs(int p) {
    ++tot;
    if(c[p]==1) s1++;
    if(c[p]==2) s2++;
    vis[p]=1;
    for(int i=0;i<g[p].size();i++) {
        int q=g[p][i];
        if(!vis[q]) {
            c[q]=3-c[p];
            dfs(q);
        }
        else if(c[p]==c[q]) flag=1;
    }
}

signed main() {
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++) {
        int t1,t2;
        scanf("%lld%lld",&t1,&t2);
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    for(int i=1;i<=n;i++) {
        if(vis[i]) continue;
        s1=s2=flag=tot=0;
        c[i]=1;
        dfs(i);
        if(flag==0) ans+=s1*s2;
        else ans+=tot*(tot-1)/2;
    }
    cout<<ans-m;
}

相关文章:

  • 2021-06-08
  • 2021-09-22
  • 2022-12-23
  • 2021-05-24
  • 2022-01-13
  • 2021-09-04
  • 2021-09-25
  • 2022-02-27
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-17
  • 2021-08-10
  • 2021-12-06
  • 2022-01-14
  • 2021-08-27
相关资源
相似解决方案