传送门:点击打开链接
题意:给一个DAG模型,要求最少的不相交的路径覆盖所有的点,即最小路径覆盖。
思路:最小路径覆盖通常把点拆成入点和出点,然后得到最大匹配数,答案就等于原点个数-最大匹配数
用二分图求最小路径覆盖的前提是,只能是DAG模型,不能有环!
#include<map> #include<set> #include<cmath> #include<ctime> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<bitset> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define fuck(x) cout<<"["<<x<<"]" #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; const int MX = 2e3 + 5; const int MS = 2e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int Head[MX], erear; struct Edge { int v, nxt; } E[MS]; void edge_init() { erear = 0; memset(Head, -1, sizeof(Head)); } void edge_add(int u, int v) { E[erear].v = v; E[erear].nxt = Head[u]; Head[u] = erear++; } int match[MX]; bool vis[MX]; bool DFS(int u) { for(int i = Head[u]; ~i; i = E[i].nxt) { int v = E[i].v; if(!vis[v]) { vis[v] = 1; if(match[v] == -1 || DFS(match[v])) { match[v] = u; return 1; } } } return 0; } int BM(int n) { int res = 0; memset(match, -1, sizeof(match)); for(int u = 1; u <= n; u++) { memset(vis, 0, sizeof(vis)); if(DFS(u)) res++; } return res; } int A[MX]; int main() { int T; //FIN; scanf("%d", &T); while(T--) { int n, m; edge_init(); scanf("%d%d", &n ,&m); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); edge_add(u, n + v); } printf("%d\n", n - BM(n)); } return 0; }