题目描述
定义: 一个不含圈的有向图G中,G的一个路径覆盖是一个其结点不相交的路径集合P,图中的每一个结点仅包含于P中的某一条路径。路径可以从任意结点开始和结束,且长度也为任意值,包括0。请你求任意一个不含圈的有向图G的最小路径覆盖数。
提示:最小路径覆盖数=G的定点数-最小路径覆盖中的边数
最小路径覆盖数=原图G的顶点数-二分图的最大匹配数
Input
t 表示有t组数据;n 表示n个顶点(n<=120);m 表示有m条边;
接下来m行,每行有两个数 i,j表示一条有向边。
Output
最小路径覆盖数
分析
这题十分的鬼畜(貌似二分图的都很鬼畜?)
因为最小路径覆盖的原理和最大独立集的原理,甚至定义都不同。然而。。他们的公式都是:
二分图顶点-最大匹配。。。
你搞笑吧?
我想了那么久却是怎么简单的东西?
我一开始还怀疑课件打错了??
然后具体求法那太简单了
连边,增广,emmm没毛病老铁
#include <iostream>
#include <cstdio>
#include <cmath>
#include <memory.h>
using namespace std;
int n,m,t,ans;
int f[121];
bool map[121][121],r[121];
int i,j,x,y;
bool fin(int a)
{
int i,d;
for (i=1;i<=n;i++)
if (map[a][i]&&!r[i])
{
d=f[i];f[i]=a;r[i]=1;
if (d==0||fin(d)) return true;
f[i]=d;
}
return false;
}
int main()
{
scanf("%d",&t);
while (t!=0)
{
t--;
scanf("%d%d",&n,&m);
memset(map,0,sizeof(map));
memset(f,0,sizeof(f));
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
map[x][y]=1;
}
ans=n;
for (i=1;i<=n;i++)
{
memset(r,0,sizeof(r));
if (fin(i)) ans--;
}
printf("%d\n",ans);
}
}