/******************************************************************************* 匈牙利算法:参考算法《算法设计技巧与分析》p444 输入:g[][]二维数组为图的链接矩阵,N为点的个数 输出:ans最大匹配值,pre[]数组:pre[i]表示与点i匹配的点 ********************************************************************************/ const int MAXN = 200+5; int N; int g[MAXN][MAXN]; bool used[MAXN]; int pre[MAXN]; //深搜找交错路径 bool dfs(int t) { int i, tmp; for(i = N+1; i <= 2*N; i++) if(g[t][i] && !used[i]) { used[i] = true; if(pre[i]== -1 || dfs(pre[i])) { pre[i] = t; return true; } } return false; } int Match() { int i, ans = 0; memset(pre, -1, sizeof(pre)); for(i = 1; i <= N; i++) { memset(used, false, sizeof(used)); if(dfs(i)) ans++; } return ans; } /* ID: linjd821 LANG: C++ TASK: air raid(pku) */ /* //有向无环图的最小路径覆盖 //1:拆点+求最大二分匹配M //2: 最小路径覆盖就是N-M */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <assert.h> #include <ctype.h> #include <map> #include <string> #include <set> #include <bitset> #include <utility> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <iostream> #include <fstream> #include <list> using namespace std; /******************************************************************************* 匈牙利算法:参考算法《算法设计技巧与分析》p444 输入:g[][]二维数组为图的链接矩阵,N为点的个数 输出:ans最大匹配值,pre[]数组:pre[i]表示与点i匹配的点 ********************************************************************************/ const int MAXN = 120+5; int N, M; int g[MAXN][MAXN*2]; bool used[MAXN*2]; int pre[MAXN*2]; //深搜找交错路径 bool dfs(int t) { int i, tmp; for(i = N+1; i <= 2*N; i++) if(g[t][i] && !used[i]) { used[i] = true; if(pre[i]== -1 || dfs(pre[i])) { pre[i] = t; return true; } } return false; } int Match() { int i, j; int ans = 0; memset(pre, -1, sizeof(pre)); //贪心初始流,但是ms没有什么效果 for(i = 1; i <= n; i++) { for(j = n+1; j <= n+m; j++) if(g[i][j] && pre[j] == -1) { pre[j] = i; ans++; break; } if(j == n+m+1) { memset(used, 0, sizeof(used)); if(dfs(i)) ans++; } } return ans; } int main() { int i, u, v, T; scanf("%d", &T); while(T--) { scanf("%d %d", &N, &M); memset(g, 0, sizeof(g)); for(i = 0; i < M; i++) { scanf("%d %d", &u, &v); g[u][v+N] = 1; } printf("%d/n", N-Match()); } return 0; }