原题: http://poj.org/problem?id=1422
题意:
路劲覆盖:在有向无环图中,选出一部分路劲(几条相连的边算一条路劲),使通过所有点恰好一次。
最小路劲覆盖:在路劲覆盖的基础上,要求路劲数量最小。在数值上=顶点数-二分图最大匹配数。
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=121,M=1210;
int n,m;
int head[N],nex[M],to[M],now;
void add(int a,int b){
to[++now]=b;nex[now]=head[a];head[a]=now;
}
int match[N];
bool vis[N];
//vis和match都是右边的点作为下标
int dfs(int u){
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(vis[v])continue;
vis[v]=1;
if(!match[v]||dfs(match[v])){match[v]=u;return 1;}
}
return 0;
}
int main(){int t;cin>>t;while(t--){
memset(match,0,sizeof(match));
memset(head,-1,sizeof(head));
now=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int a,b;scanf("%d%d",&a,&b);
add(a,b);
}
int ans=0;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
printf("%d\n",n-ans);
}}