因为点可以重复经过,所以要扩展边以把间接的变成直接的。。。。
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int N = 510; int g[N][N]; int linker[N]; bool vis[N]; int n, m; bool dfs(int u) { for (int i = 1;i <= n;++i) { if (!vis[i] && g[u][i] && u != i) { vis[i] = true; if (linker[i] == -1 || dfs(linker[i])) { linker[i] = u; return true; } } } return false; } int hungary() { memset(linker, -1,sizeof linker); int ans = 0; for (int i = 1;i <= n;++i) { memset(vis,false,sizeof vis); if (dfs(i)) ans++; } return ans; } void floyd() { for (int k = 1;k <= n;++k) { for (int i = 1;i <= n;++i) { for (int j = 1;j <= n;++j) if (g[i][k] && g[k][j]) g[i][j] = 1; } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(scanf("%d%d",&n,&m) && (n + m)) { memset(g, 0,sizeof g); int u, v; for (int i = 1;i <= m;++i) { scanf("%d%d",&u,&v); g[u][v] = 1; } floyd(); printf("%d\n", n - hungary()); } return 0; }