直接先传递闭包,等同于扩边,最后就是一般最小路径覆盖的做法了。
const int maxn = 501;
int g[maxn][maxn];
int linker[maxn];
bool vis[maxn];
int n, m;
bool dfs(int u) {
for (int v = 1;v <= n;++v) {
if (g[u][v] && !vis[v]) {
vis[v] = true;
if (linker[v] == -1 || dfs(linker[v])) {
linker[v] = u;
return true;
}
}
}
return false;
}
int Hungary() {
memset(linker, -1,sizeof linker);
int ret = 0;
for (int i = 1;i <= n;++i) {
memset(vis, false,sizeof vis);
if (dfs(i)) ret++;
}
return ret;
}
void floyd() {
for (int k = 1;k <= n;++k) {
for (int i = 1;i <= n;++i) {
for (int j = 1;j <= n;++j) {
g[i][j] = g[i][j] || (g[i][k] && g[k][j]);
}
}
}
}
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// clock_t _ = clock();
while(~scanf("%d%d",&n, &m)) {
if (n == 0 && m == 0) break;
memset(g, 0,sizeof g);
int u, v;
for (int i = 1;i <= m;++i) {
scanf("%d%d", &u, &v);
g[u][v] = 1;
}
// cout << "n = " << n << endl;
floyd();
printf("%d\n", n - Hungary());
}
// printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);
return 0;
}