POJ3041 - Asteroids

本文介绍了一个基于最大匹配算法解决特定问题的方法。通过构建二分图并利用最大匹配算法找到最小点覆盖数,解决了关于障碍物的射击次数问题。文章详细展示了算法实现过程,并附带了完整的C语言代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此题说难也难说简单也简单。关键就看有没有理解这样的一条定理:

最小点覆盖数=最大匹配数

解题思路如下:

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值