【SSL1340】最小路径覆盖

Description

定义: 一个不含圈的有向图G中,G的一个路径覆盖是一个其结点不相交的路径集合P,图中的每一个结点仅包含于P中的某一条路径。路径可以从任意结点开始和结束,且长度也为任意值,包括0。请你求任意一个不含圈的有向图G的最小路径覆盖数。

提示:最小路径覆盖数=G的定点数-最小路径覆盖中的边数
最小路径覆盖数=原图G的顶点数-二分图的最大匹配数

Input

t 表示有t组数据;n 表示n个顶点(n<=120);m 表示有m条边;
   接下来m行,每行有两个数 i,j表示一条有向边。

Output

最小路径覆盖数

Sample Input

2 
4
3
3 4
1 3
2 3
3
3
1 3
1 2
2 3

Sample Output

2
1

思路:

最小路径覆盖

代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

int t, n, m, head[200], tot, v[200], link[200];
struct node
{
	int to, next;
}b[1000100];

void add(int x, int y)
{
	b[++tot]=(node){y, head[x]};
	head[x]=tot;
}
int find(int x)
{
	for(int i=head[x]; i; i=b[i].next)
	{
		int y=b[i].to;
		if(!v[y])
		{
			v[y]=1;
			int q=link[y];
			link[y]=x;
			if(q==0||find(q))
				return 1;
			link[y]=q;
		}
	}
	return 0;
}
int main(){
	scanf("%d", &t);
	while(t--)
	{
		scanf("%d%d", &n, &m);
		for(int i=1; i<=m; i++)
		{
			int x, y;
			scanf("%d%d", &x, &y);
			add(x, y);
		}
		int ans=0;
		for(int i=1; i<=n; i++)
		{
			memset(v, 0, sizeof(v));
			if(find(i))
				ans++;
		}
		printf("%d\n", n-ans);
		tot=0;
		memset(head, 0, sizeof(head));
		memset(link, 0 ,sizeof(link));
	}
	return 0;
}

你可能感兴趣的:(题解,匹配)