这题是DAG中的最小路径覆盖问题
【算法】
最小路径覆盖,即在当前图中,找N条路径,使得这N条路径能够覆盖图中的所有顶点,N的最小值就是我们要求的值
【题意】
一个城市里有n个十字路口,m条街道,要在十字路口上降落伞兵,伞兵可以搜索到降落的那个路口或者沿着此路口所连接的街道搜索到其他路口,使伞兵能找到全部路口,求此时的最小值,即降落伞兵的最小数量
【思路】
最小路径覆盖 = 图的顶点数 - 最大匹配数
当一个路口确实存在在图中 并且 没有被搜索到时,它可以被搜索到
当一个路口不能被沿着的街道连接时 或者 能沿着街道搜索到时,这个路口将能被找到;前面两个条件不能同时完成,是二取其一的情况
【AC代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#define N 125
using namespace std;
int map[N][N]; //表示这样的点是否有在图中存在
int vis[N]; //表示点是否有被搜索过
int link[N]; //表示点是否有被连接到
int n,m;
int find(int k)
{
for(int i=1; i<=n; i++)
{
if(!vis[i] && map[k][i])
{
vis[i] = 1;
if(link[i]==-1 || find(link[i]))
{
return 1;
}
}
}
return 0;
}
int hug() //最大匹配数
{
int ans = 0;
memset(vis,0,sizeof(vis));
memset(link,-1,sizeof(link));
for(int i=1; i<=n; i++)
{
if(find(i))
ans++;
}
return ans;
}
int main()
{
int t,u,v;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n, &m);
memset(map,0,sizeof(map));
for(int i=1; i<=m; i++)
{
scanf("%d%d", &u, &v);
map[u][v] = 1;
}
int ans = n-hug();
printf("%d\n", ans);
}
return 0;
}