此题说难也难说简单也简单。关键就看有没有理解这样的一条定理:
最小点覆盖数=最大匹配数
解题思路如下:
1、以行和列分别建立两个顶点集V1,V2
2、将障碍物(x1,y1)视为两个顶点集中的两点V1(x1),V2(y1)的边
3、求V1和V2的最大二分匹配,由最小点覆盖数=最大匹配数可知,此即为答案(the minimum number of times Bessie must shoot)
//Memory Time
//956K 0MS
#include<stdio.h>
int edge[501][501];
int edgeNum[501];
int couple[501];
bool isVisited[501];
bool isHoped[501];
int search(int N);
bool dfs(int src);
int main()
{
int N, K;
scanf("%d %d", &N, &K);
for(int i = 1; i <= N; i++)
{
edgeNum[i] = 0;
couple[i] = -1;
isVisited[i] = 0;
isHoped[i] = 1;
}
for(int i = 0; i < K; i++)
{
int src,dst;
scanf("%d %d", &src, &dst);
edge[src][edgeNum[src]] = dst;
edgeNum[src]++;
}
printf("%d\n", search(N));
return 0;
}
int search(int N)
{
int temp = 0;
for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= N; j++)
{
isVisited[j] = 0;
}
if(dfs(i))
temp++;
}
return temp;
}
bool dfs(int src)
{
int tempNum = edgeNum[src];
for(int i = 0; i < tempNum; i++)
{
int tempDst = edge[src][i];
if(isVisited[tempDst] == 0 && isHoped[tempDst])
{
isVisited[tempDst] = 1;
if(couple[tempDst] == -1)
{
couple[tempDst] = src;
return 1;
}
else
{
if(dfs(couple[tempDst]))
{
couple[tempDst] = src;
return 1;
}
else
{
isHoped[tempDst] = 0;
}
}
}
}
return 0;
}