您的位置:首页 > 其它

二分图的最大匹配(最小路径覆盖,最小点覆盖)

2009-03-09 23:27 302 查看
/*******************************************************************************
匈牙利算法:参考算法《算法设计技巧与分析》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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐