[BZOJ 2547] 玩具兵
Link:
Solution:
很容易通过解可行性的单调性想到二分答案,接下来考虑如何验证解
发现一个很奇妙的条件:步兵和骑兵的个数相同
因此交换位置时不用考虑可行性,保证能完成交换(口胡证明一下就行了)
于是可以将每一次交换位置想成转变职业(不用考虑能否交换)
每一个士兵先用$bfs$预处理其到每个格子需要的转变次数。
对于一次$check(mid)$,由于上述性质,$交换次数<=mid$的移动都是合法的
只要先跑一遍$交换次数<=mid$的士兵和位置的最大匹配$Max_{Match}$
再考虑$Max_{Match}+mid>=2*K$是否成立即可(多出的贡献$mid$是对于“天兵”的特殊处理)
Code:
#include <bits/stdc++.h> using namespace std;
typedef pair<int,int> P;
#define X first
#define Y second
const int MAXN=1e3+;
int dx[]={,,,-},dy[]={,-,,};
P dat[MAXN],ly[MAXN];
int N,M,K,T,h[MAXN][MAXN],tot=;
int match[MAXN],dist[MAXN][MAXN],w[MAXN][MAXN];
bool vis[MAXN]; void bfs(int st_x,int st_y,int f)
{
queue<P> que;que.push(P(st_x,st_y));
memset(dist,0x3f,sizeof(dist));dist[st_x][st_y]=;
while(!que.empty())
{
P t=que.front();que.pop();
for(int i=;i<;i++)
{
int fx=t.X+dx[i],fy=t.Y+dy[i],delta;
if(fx< || fx>N || fy< || fy>M) continue;
if(f^(dist[t.X][t.Y]&))
if(h[fx][fy]<=h[t.X][t.Y]) delta=; else delta=;
else
if(h[fx][fy]>=h[t.X][t.Y]) delta=; else delta=;
if(dist[fx][fy]>dist[t.X][t.Y]+delta)
{
dist[fx][fy]=dist[t.X][t.Y]+delta;
que.push(P(fx,fy));
}
}
}
} bool dfs(int u,int lim)
{
for(int i=;i<=tot;i++)
if(!vis[i] && w[u][i]<=lim)
{
vis[i]=true;
if(match[i]==- || dfs(match[i],lim))
{
match[i]=u;
return true;
}
}
return false;
} bool check(int x)
{
memset(match,-,sizeof(match));
int ret=;
for(int i=;i<=*K;i++)
{
memset(vis,,sizeof(vis));
if(dfs(i,x)) ret++;
}
return (ret+x)>=*K;
} int main()
{
scanf("%d%d%d%d",&N,&M,&K,&T);
for(int i=;i<=*K+;i++) scanf("%d%d",&dat[i].X,&dat[i].Y);
for(int i=;i<=T;i++)
{
int x,y,z;scanf("%d%d%d",&x,&y,&z);
while(z--) ly[++tot]=P(x,y);
}
for(int i=;i<=N;i++) for(int j=;j<=M;j++) scanf("%d",&h[i][j]); for(int i=;i<=*K;i++) //bfs预处理
{
if(i<=K) bfs(dat[i].X,dat[i].Y,);
else bfs(dat[i].X,dat[i].Y,);
for(int j=;j<=tot;j++) w[i][j]=dist[ly[j].X][ly[j].Y];
} int l=,r=K*; //二分答案
while(l<=r)
{
int mid=(l+r)>>;
if(check(mid)) r=mid-;
else l=mid+;
}
printf("%d",l);
return ;
}
Review:
此题的难点在于将 交换位置$->$转变职业
还是要注意题目中的特殊性质(EX:两职业个数相同),看看能不能推出一些奇妙的结论
[BZOJ 2547] 玩具兵的更多相关文章
- [Bzoj 2547] [Ctsc2002] 玩具兵
2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 317 Solved: 152[Submit][Status] ...
- BZOJ 2547: [Ctsc2002]玩具兵(二分答案+二分图匹配)
传送门 解题思路 可以发现天兵不用管,答案的一个上界是\(2*k\),就是天兵一个个换.刚开始写了个拆\(6\)点的网络流,调了半天发现自己假了..说说正解,首先可以发现交换士兵其实就是种类的交换,那 ...
- bzoj 1010 玩具装箱toy -斜率优化
P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具 ...
- [bzoj2547]玩具兵<Spfa+二分+匈牙利算法>
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2547 挺有意思的一道题,这道题可以划分成几个小题....... 题目大意: 三个兵种在一个 ...
- BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- 【斜率DP】BZOJ 1010:玩具装箱
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7537 Solved: 2888[Submit][St ...
- BZOJ 1055 玩具取名
Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使 ...
- BZOJ 1010: 玩具装箱toy (斜率优化dp)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- BZOJ2547 CTSC2002玩具兵(最短路径+二分答案+最大流)
先不考虑只有一个显得有些特殊的天兵. 可以发现超能力的作用实质上是使兵更换职业.每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地 ...
随机推荐
- Python基础简介与简单使用
Python介绍 Python发展史 1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器.Python这个名字,来自Guido所挚爱的电视剧Monty Python’s Flyi ...
- 一个初学者的辛酸路程-jQuery
前言: 主要概要: 1.HTML+CSS补充 2.DOM事件 3.jQuery示例 内容概要: 1.布局 代码如下 <!DOCTYPE html> <html lang=" ...
- (原)Unreal渲染模块 管线 - 着色器(1)
@author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...
- heat launch an instance
在包含Orchestration服务的环境中,可以创建启动实例的堆栈 创建yam文件 heat_template_version: 2015-10-15 description: Launch a b ...
- iOS 实现设备应用之间的相互切换
今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...
- HttpRuntime.Cache再学习
摘抄: 可以看到:读缓存,其实是在调用Get方法,而写缓存则是在调用Insert方法的最简单的那个重载版本. 注意了:Add方法也可以将一个对象放入缓存,这个方法有7个参数,而Insert也有一个签名 ...
- Codeforces 498D Traffic Jams in the Land | 线段树
题目大意: 给坐标轴1~n的点,每个点有一个权值,从一个点走到下一个点需要1s,如果当前时间是权值的倍数就要多花1s 给出q组操作,C表示单点修改权值,A表示询问0时刻x出发到y的时间 题解:因为权值 ...
- 大型C++项目必须注意的几个小问题
大型C++项目必须注意的几个小问题 有些问题对于小型的C++项目来说可能无关紧要,但对于大中型C++项目来讲,这些问题却成了大问题.什么样的项目算是小型项目呢,什么样的算是大中型项目呢,我认为10万L ...
- 电阻 (resistance)
电阻 (resistance) 题目描述 每次小x物理作业没做完时,总是会去和老师交流感情,他们之间由此建立起来良好的师生关系.于是有一天,老师带着一道物理难题来见小x. 这道题给出了一个有n个电阻的 ...
- 【HDU 5961 传递】
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission ...