列表

详情


NC236754. 炸弹

描述

给一张  的方格图,方格图中有m个障碍物。Playf想要消除这些障碍物,为此他准备了一些炸弹。每一个炸弹可以消除一行或者一列的所有障碍物。因为炸弹很昂贵,Playf想用尽可能少的炸弹消除所有障碍物,你能帮帮他吗?

输入描述

第一行输入两个整数  分别表示方格图的大小和障碍物总数。
接下来m行,每行输入两个整数  ,表示一个障碍物在方格图内的坐标。输入保证没有两个障碍物的坐标相同。

输出描述

输出一行一个整数,表示Playf至少需要用多少炸弹才能消除所有障碍物。

示例1

输入:

3 4
1 1
1 3
2 2
3 2

输出:

2

说明:

输入数据如下:
X.X
.X.
.X.
其中X表示障碍物。
Playf至少需要两个炸弹才能消除所有障碍物,第一个炸弹可以用于消除第一行的障碍物,第二个炸弹用于消除第二列的障碍物。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 24ms, 内存消耗: 652K, 提交时间: 2022-07-05 15:44:58

#include<bits/stdc++.h>
using namespace std;
int n, m;
bool G[505][505], vis[505];
int link[505];  // y连的 
int ans;
int dfs(int x){
	for(int i=1;i<=n;i++){
		if(!G[x][i] || vis[i]) continue;
		vis[i] = 1;
		if(link[i] == 0 || dfs(link[i])){
			link[i] = x;
			return 1;
		}
	}
	return 0;
}
void start(){
	for(int i=1;i<=n;i++){
		memset(vis, 0, sizeof(vis));
		ans += dfs(i);
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
        int x, y;
		cin>>x>>y;
		G[x][y] = true;
	}
	start();
	cout<<ans<<endl;
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 19ms, 内存消耗: 12444K, 提交时间: 2023-08-09 22:14:42

#include<bits/stdc++.h>

using namespace std;
int n,m,cnt;
vector<int>e[505010];
int vis[250010],p[250010];
bool find(int x)
{
	vis[x]=cnt;
	for(auto y:e[x]){
		if(!p[y]||(vis[p[y]]!=cnt&&find(p[y]))){
			p[y]=x;
			return 1;
		}
	}
	return 0;
}
int match()
{
	int ans=0;
	for(int i=1;i<=n;i++){
		cnt++;
		if(find(i))
			ans++;
	}
	return ans;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y;
		cin>>x>>y;
		e[x].push_back(y);
	}
	cout<<match()<<"\n";
	return 0;
}

上一题