最小路劲覆盖(二分图最大匹配)

原题: 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);
}}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/86563475