题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1151
题目大意:考虑一个城市的街道都是单向的并且所有的道路都是从一个十字路口到另一个十字路口。从一个起点出发,沿着路走你永远都不可能回到起点,
也就是说道路没有环。
对于这样的一个假设,你的任务是编写一个程序,它可以找到让最小数量的伞兵,他们可以沿着路走经过所有的十字路口。而且一个十字路口不能被两个,
或两个以上的人经过。每一个伞兵降落在一个十字路口,可以访问其他城镇街道后的十字路口。没有限制的起动交叉对于每个伞兵。
解题思路:因为街道是有向的,而且不存在环,要到达所有的顶点我们可以转换为二分图的最小路径覆盖。
#include<stdio.h>
#include<string.h>
#define maxn 150
int map[maxn][maxn],mark[maxn],no_of_intersections,no_of_streets;
bool vis[maxn];
bool dfs(int v)
{
for(int i = 1; i <= no_of_intersections; i++)
{
if(!map[v][i] || vis[i])
continue;
vis[i] = true;
if(mark[i] == -1 || dfs(mark[i]))
{
mark[i] = v;
return true;
}
}
return false;
}
int main()
{
int t,s,e,i;
scanf("%d",&t);
while( t-- )
{
scanf("%d%d",&no_of_intersections,&no_of_streets);
memset(map,0,sizeof(map));
for( i = 0; i < no_of_streets; i++)
{
scanf("%d%d",&s,&e);
map[s][e] = 1;
}
memset(mark,-1,sizeof(mark));
int ans = 0;
//求最大匹配数
for( i = 1; i <= no_of_intersections; i++)
{
memset(vis,false,sizeof(vis));
if(dfs(i))//深度搜索增广路
ans++;
}
//最小路径覆盖 = 点的个数 - 最大匹配数
printf("%d\n",no_of_intersections - ans);
}
return 0;
}