划了一天水,其实我还是有点愧疚的。

传送门

其实是水题,然而我真是太蠢了。。。

首先不考虑天兵,其他兵要到一个点去一定是通过它-另一种兵-它……这样多次交换的,并且交换对象是无所谓的,和它换的兵最终会是在原位置。

而且骑兵和步兵的数量相等,就不存在一个兵找不到人跟它换的情况,那么一个确定的方案下换的次数最多的兵换的次数就是答案。

先spfa找出每个兵到每个位置的最小换的次数,然后二分答案,把每个兵向它可以到的地方连边,跑最大匹配,考虑到还有天兵,而天兵是可以一步登天的超神存在,所以如果最大匹配数+现在check的ans>=总兵数即OK。

因为一直在划水,断断续续地写这个代码 ,又困得要命,仿佛活在梦中,结果竟然1A了,神奇。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=;
typedef long long LL;
using namespace std;
int n,m,k,t,R[N],h[N][N],dis[N][N],dp[N][N][],vis[N][N][];
int dx[]={,,,-},dy[]={,-,,}; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int x,y,o;
node(){}
node(int x,int y,int o):x(x),y(y),o(o){}
}b[N],p[N]; queue<node>que;
void spfa(int sx,int sy,int k) {
memset(dp,,sizeof(dp));
if(k) dp[sx][sy][]=,que.push(node(sx,sy,));
else dp[sx][sy][]=,que.push(node(sx,sy,));
while(!que.empty()) {
node now=que.front();
que.pop();
int x=now.x,y=now.y,o=now.o;
vis[x][y][o]=;
for(int i=;i<;i++) {
int xx=now.x+dx[i],yy=now.y+dy[i],oo,t;
if(xx>=&&xx<=n&&yy>=&&yy<=m) {
if((o==&&h[xx][yy]>=h[x][y])||(o==&&h[xx][yy]<=h[x][y])) t=dp[x][y][o],oo=o;
else t=dp[x][y][o]+,oo=o^;
if(dp[xx][yy][oo]>t) {
dp[xx][yy][oo]=t;
if(!vis[xx][yy][oo]) {
que.push(node(xx,yy,oo));
vis[xx][yy][oo]=;
}
}
}
}
}
} int ok[N][N],vs[N],pr[N],sum[N];
int find(int x) {
for(int i=;i<=*k;i++) if(ok[x][i]&&!vs[i]) {
vs[i]=;
if(!pr[i]||find(pr[i])) {
pr[i]=x;
return ;
}
}
return ;
} int ck(int ans) {
int res=;
for(int i=;i<=*k;i++)
for(int j=;j<=t;j++) {
if(dis[i][j]<=ans)
for(int kk=;kk<=R[j];kk++)
ok[i][sum[j-]+kk]=;
else for(int kk=;kk<=R[j];kk++)
ok[i][sum[j-]+kk]=;
}
memset(pr,,sizeof(pr));
for(int i=;i<=*k;i++) {
memset(vs,,sizeof(vs));
if(find(i)) res++;
}
if(res+ans>=*k) return ;
else return ;
} int main() {
read(n); read(m); read(k); read(t);
for(int i=;i<=*k+;i++) {
read(b[i].x);
read(b[i].y);
}
for(int i=;i<=t;i++) {
read(p[i].x);
read(p[i].y);
read(R[i]); sum[i]=sum[i-]+R[i];
}
for(int i=;i<=n;i++) for(int j=;j<=m;j++) read(h[i][j]);
memset(dis,,sizeof(dis));
for(int i=;i<=*k;i++) {
spfa(b[i].x,b[i].y,(i<=k));
for(int j=;j<=t;j++)
dis[i][j]=min(dp[p[j].x][p[j].y][],dp[p[j].x][p[j].y][]);
}
if(ck()) {
puts(""); return ;
}
int l=,r=1e9,ans=r;
while(l<=r) {
int mid=((l+r)>>);
if(ck(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d\n",ans);
return ;
}
/*
4 6 2 5
1 1 1 5 4 1 4 5 3 3
1 2 1 2 6 1 3 2 1 3 6 1 4 3 1
3 2 6 1 3 5
2 1 7 4 4 6
2 3 1 4 3 4
4 3 4 3 2 3
*/

bzoj2547: [Ctsc2002]玩具兵的更多相关文章

  1. BZOJ2547 CTSC2002玩具兵(最短路径+二分答案+最大流)

    先不考虑只有一个显得有些特殊的天兵. 可以发现超能力的作用实质上是使兵更换职业.每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地 ...

  2. [Bzoj 2547] [Ctsc2002] 玩具兵

    2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 152[Submit][Status] ...

  3. BZOJ 2547: [Ctsc2002]玩具兵(二分答案+二分图匹配)

    传送门 解题思路 可以发现天兵不用管,答案的一个上界是\(2*k\),就是天兵一个个换.刚开始写了个拆\(6\)点的网络流,调了半天发现自己假了..说说正解,首先可以发现交换士兵其实就是种类的交换,那 ...

  4. [bzoj2547]玩具兵<Spfa+二分+匈牙利算法>

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2547 挺有意思的一道题,这道题可以划分成几个小题....... 题目大意: 三个兵种在一个 ...

  5. [BZOJ 2547] 玩具兵

    Link: BZOJ 2547 传送门 Solution: 很容易通过解可行性的单调性想到二分答案,接下来考虑如何验证解 发现一个很奇妙的条件:步兵和骑兵的个数相同 因此交换位置时不用考虑可行性,保证 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  8. DNF NPK包名对照一览表

    文章转载自:http://bbs.exrpg.com/thread-107917-1-1.html ┌ sprite.NPK                                      ...

  9. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

随机推荐

  1. 设置Hadoop+Hbase集群pid文件存储位置

    有时候,我们对运行几天或者几个月的hadoop或者hbase集群做停止操作,会发现,停止命令不管用了,为什么呢? 因为基于java开发的程序,想要停止程序,必须通过进程pid来确定,而hadoop和h ...

  2. Java后端WebSocket的Tomcat实现(转)

    文章摘要随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端 ...

  3. C++返回引用的需求

    1.重载+=操作符返回*this或者某个参数的引用可以方便链式调用,比如C++流操作就是cout<< a << b << c这样的,就是靠不停返回stream的引用 ...

  4. Linux操作系统系列-Linux基础

    概述 先了解下unix,unix是一个多任务.多用户的操作系统,并且是收费的操作系统. 1991年的10月5日,林纳斯·托瓦兹在comp.os.minix新闻组上发布消息,正式向外宣布Linux内核的 ...

  5. LeetCode第一题—— Two Sum(寻找两数,要求和为target)

    题目描述: Given an array of integers, return indices of the two numbers such that they add up to a speci ...

  6. re模块补充

    )# 后面加数字代表前面多少个进行替换print(ret8) # stars466c7#7.subn() 会返回替换了多少次ret9=re.subn('\d','asd','sh8sd6sds7smm ...

  7. csps模拟69chess,array,70木板,打扫卫生题解

    题面:https://www.cnblogs.com/Juve/articles/11663898.html 69: 本以为T2傻逼题结果爆零了...T3原题虽然打的不是正解复杂度但是都不记得做过这道 ...

  8. 黑裙晖安装后修改mac和sn

    d当前使用6.2 打开putty sudo -i 然后在/tmp目录下创建一个临时目录,名字随意,如:boot mkdir -p /tmp/boot 第四步:切换到dev目录 cd /dev 第五步: ...

  9. tomcat结构图

  10. zip压缩工具类

    java将有关zip压缩的内容都封装在java.util.zip宝中,用java实现zip压缩,不用考虑压缩算法,java已经将这些进行了封装 实际上用java实现zip压缩涉及的就是一个“输入输出流 ...