【2018ACM山东省赛 - B】Bullet(二分 + 二分图匹配,匈牙利算法,卡常)

题干:

Problem Description

In GGO, a world dominated by gun and steel, players are fighting for the honor of being the strongest gunmen. Player Shino is a sniper, and her aimed shot kills one monster at a time. Now she is in an n×nn \times nn×n map, and there are monsters in some grids. Each monster has an experience. As a master, however, Shino has a strange self-restrain. She would kill at most one monster in a column, and also at most one in a row. Now she wants to know how to get max experience, under the premise of killing as many monsters as possible.

Input

The first line contains an integer nnn. (n<=500)
Then n lines follow. In each line there are n integers, and AijAijAij represents the experience of the monster at grid (i,j)(i,j)(i,j). If Aij=0Aij=0Aij=0, there is no monster at grid (i,j)(i,j)(i,j).

The experience is the minimal experience of all the monster which are killed.

It guaranteed that the maximum of the experience of the monster is not larger than 10^9

Output

One integer, the value of max experience.

Sample Input

2
2 0
1 8

Sample Output

2

题目大意:

   就是一个打怪兽的游戏,你可以选择一个位置打怪兽,你可以打很多怪兽,但是每一行或者每一列最多打一个怪兽(和N皇后问题一样),每个位置上的怪兽都有一个权值(二维数组中的值),如果值为0代表这里没有怪兽,你打完怪兽可以获得的经验值为你所有打的怪兽的权值的最小值。问你最大可以获得多大的权值。

解题报告:

   二分这个最小值,然后匈牙利check一下即可。

   这题卡常(其实是复杂度本身就不允许),但是加了优化可以过。

  优化1:memset改for(不过对这种单组样例的可能用处不大)

  优化2:每次二分之后都新建边,这个对二分图的优化较大。

  优化3:可以先离散化数据然后对数据二分,这样降低了二分次数(不过效果并不是很好,甚至500ms变成了900ms)

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 500 + 5;
struct Edge {
	int to,ne,w;
} e[MAX*MAX];
int tot,head[MAX];

void add(int u,int v,int w) {
	e[++tot].to = v;
	e[tot].w = w;
	e[tot].ne = head[u];
	head[u] = tot;
}
int all,tmp,n,a[MAX][MAX];
int nxt[MAX];
bool use[MAX];
bool find(int x) {
	for(int j = head[x]; ~j; j = e[j].ne) {
		int v = e[j].to;
		if(use[v] == 1) continue;		
		if(e[j].w < tmp) continue;
		use[v]=1;
		if(nxt[v] == 0 || find(nxt[v])) {
			nxt[v] = x;
			return 1;
		}
	}
	return 0 ;
}
int match() {
//	memset(nxt,0,sizeof nxt);
	for(int i = 1; i<=n; i++) nxt[i] = 0;
	int res = 0;
	for(int i = 1; i<=n; i++) {
		for(int i = 1; i<=n; i++) use[i] = 0;
		if(find(i)) res++;
	}
	return res;
}
bool ok(int x) {
	tmp = x;
	if(match() == all) return 1;
	else return 0 ;
}
int main()
{	
	tot=0;
	int maxx=0;
	cin>>n;
	for(int i = 1; i<=n; i++) head[i] = -1;
	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=n; j++) {
			scanf("%d",&a[i][j]);maxx=max(maxx,a[i][j]);
		}
	}
	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=n; j++) {
			if(a[i][j]) add(i,j,a[i][j]);
		}
	}
	all = match();
	if(maxx == 0) {
		printf("0\n");return 0 ;
	}
	int l = 1,r = maxx,mid,ans=0;
	while(l<=r) {
		mid=(l+r)>>1;
		tot=0;
		for(int i = 1; i<=n; i++) head[i] = -1;
		for(int i = 1; i<=n; i++) {
			for(int j = 1; j<=n; j++) {
				if(a[i][j] >= mid) add(i,j,a[i][j]);
			}
		}
		if(ok(mid)) ans = mid,l = mid+1;
		else r = mid-1;
	}
	printf("%d\n",ans);
	return 0 ;
}

 

全部评论

相关推荐

bg双非本科,方向是嵌入式。这次秋招一共拿到了&nbsp;8&nbsp;个&nbsp;offer,最高年包&nbsp;40w,中间也有一段在海康的实习经历,还有几次国家级竞赛。写这篇不是想证明什么,只是想把自己走过的这条路,尽量讲清楚一点,给同样背景的人一个参考。一、我一开始也很迷茫刚决定走嵌入式的时候,其实并没有一个特别清晰的规划。网上的信息很零散,有人说一定要懂底层,有人说项目更重要,也有人建议直接转方向。很多时候都是在怀疑:1.自己这种背景到底有没有机会2.现在学的东西到底有没有用3.是不是已经开始晚了这些问题,我当时一个都没答案。二、现在回头看,我主要做对了这几件事第一,方向尽早确定,但不把自己锁死。我比较早就确定了嵌入式这个大方向,但具体做哪一块,是在项目、竞赛和实习中慢慢调整的,而不是一开始就给自己下结论。第二,用项目和竞赛去“证明能力”,而不是堆技术名词。我不会刻意追求学得多全面,而是确保自己参与的每个项目,都能讲清楚:我负责了什么、遇到了什么问题、最后是怎么解决的。第三,尽早接触真实的工程环境。在海康实习的那段时间,对我触动挺大的。我开始意识到,企业更看重的是代码结构、逻辑清晰度,以及你能不能把事情说清楚,而不只是会不会某个知识点。第四,把秋招当成一个需要长期迭代的过程。简历不是一次写完的,面试表现也不是一次就到位的。我会在每次面试后复盘哪些问题没答好,再针对性补。三、我踩过的一些坑现在看也挺典型的:1.一开始在底层细节上纠结太久,投入产出比不高2.做过项目,但前期不会总结,导致面试表达吃亏3.早期有点害怕面试,准备不充分就去投这些弯路走过之后,才慢慢找到节奏。四、给和我背景相似的人一点建议如果你也是双非,准备走嵌入式,我觉得有几件事挺重要的:1.不用等“准备得差不多了”再投2.项目一定要能讲清楚,而不是做完就算3.不要只盯着技术,多关注表达和逻辑很多时候,差的不是能力,而是呈现方式。五、写在最后这篇总结不是标准答案,只是我个人的一次复盘。后面我会陆续把自己在嵌入式学习、竞赛、实习和秋招中的一些真实经验拆开来讲,希望能对后来的人有点帮助。如果你正好也在这条路上,希望你能少走一点弯路。
x_y_z1:蹲个后续
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务