核心思路
考虑图中存在 c 个连通块
考虑每一个连通块的贡献。
一条点如果m为其入度,则他会被使用m次。
若存在欧拉路。则一个连通块的贡献是(m-1)。(不用回到起点,所以不必为m)
若不存在,则考虑添加x条边来达到目的。
将出度不够的点连一条于入度不足的点上。
由于有向图 :入度总和 = 出度总和 所以,必然可以匹配成功。
某一个连通块缺了x个入度,则则连x-1条可构成欧拉路径(可以有两个点少1或者多1)。
这里,可以感性地理解成增加了x-1条边,就会有x-1个点被调用。
初始化一下,ans = m+1(至少的数量)
AC代码
#include<bits/stdc++.h>
using namespace std;
int c;
vector<int> g[114514];
int ru[114514],chu[114514];
int xiao = 114514,n,m,ans;
int b[114514];
int x;
void dfs(int u){
//x++;
b[u] =1;
if(chu[u] > ru[u])x+=(chu[u]-ru[u]);
for(int v:g[u]){
if(b[v])continue;
dfs(v);
}
}
int main(){
cin>>m;
for(int i = 1;i <= m;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
ru[v]++;
chu[u]++;
xiao = min({xiao,u,v});
n = max({n,u,v});
}
ans = m+1;
for(int i = xiao;i <= n;i++){
if(!b[i]&&(chu[i]>0||ru[i]>0)){//访问 + 特判孤立点
c++;
x = 0;
dfs(i);
if(x >=1)ans+=(x-1);
}
}
if(c >=2){
ans+=(c-1);
}
cout<<ans;
return 0;
}