不想写模板了来水几篇题解。。。
最开始窝写的贪心。。然后就WA了。。 = =
正解是二分图匹配。。。
首先枚举中心点。。然后用需要添加的边加上需要删除的边求个最小值就是答案了。。。
设与Center相关的边数为A
需要添加的边 = (2 * N -1 - A) + (N - 1 - match)
需要删除的边 = (M - A) - match
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int N, M;
bool map[505][505];
int in[505], out[505];
int match[505];
bool vis[505];
bool dfs(int u, int C)
{
for (int v = 1; v <= N; ++ v) {
if (!map[u][v] || vis[v] || v == C) continue;
vis[v] = 1;
if (match[v] == -1 || dfs(match[v], C)) {
match[v] = u; return 1;
}
}
return 0;
}
inline int Match(int Center)
{
memset(match, -1, sizeof(match));
int res = 0;
for (int i = 1; i <= N; ++i) if (i != Center) {
memset(vis, 0, sizeof(vis));
res += dfs(i, Center);
}
return 2 * res;
}
inline int Make(int Center)
{
int Edge = (in[Center] + out[Center] - map[Center][Center]);
return (N << 1) - 1 + M - (Edge << 1) + (N - 1) - Match(Center);
}
int main()
{
ios :: sync_with_stdio(false);
cin >> N >> M;
int u, v;
for (int i = 1; i <= M; ++ i) {
cin >> u >> v;
++ out[u]; ++ in[v];
map[u][v] = 1;
}
int ans = 0x7fffffff;
for (int c = 1; c <= N; ++ c)
ans = min(ans, Make(c));
cout << ans << endl;
return 0;
}