先不考虑只有一个显得有些特殊的天兵。

  可以发现超能力的作用实质上是使兵更换职业。每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地方,不会造成其中一个次数增加。

  于是预处理出每个兵到达每个位置的最少代价。之后二分答案,把每个兵向可以到达的目标位置连边。跑最大流就可以知道是否可行。

  最后考虑天兵。天兵可以任意游走,并且与天兵换职业的兵可以直接到达目的地。那么在最大流的结果上加上二分出的答案即可,因为每次使用超能力都可以送走一个兵。

  1A爽爆。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 110
int n,m,k,l,dis[N][N][N],a[N][N],w[N][N],ans;
struct pos{int x,y;}u[N],v[N];
namespace shortestpath
{
int d[N*N<<],p[N*N<<],t=;
int wx[]={,,-,},wy[]={,,,-};
bool flag[N*N<<];
struct data{int to,nxt,len;}edge[N*N<<];
int trans(int x,int y,int op){return op*n*m+(x-)*m+y;}
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
struct data2
{
int x,d;
bool operator <(const data2&a) const
{
return d>a.d;
}
};
priority_queue<data2> q;
void make()
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
for (int k=;k<;k++)
if (i+wx[k]>&&i+wx[k]<=n&&j+wy[k]>&&j+wy[k]<=m)
if (a[i][j]<a[i+wx[k]][j+wy[k]])
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
else if (a[i][j]>a[i+wx[k]][j+wy[k]])
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
else
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
}
}
void dijkstra(int start)
{
memset(d,,sizeof(d));d[trans(u[start].x,u[start].y,start>k)]=;
memset(flag,,sizeof(flag));
while (!q.empty()) q.pop();
q.push((data2){trans(u[start].x,u[start].y,start>k),});
for (int i=;i<=(n*m<<);i++)
{
while (!q.empty()&&flag[q.top().x]) q.pop();
if (q.empty()) break;
data2 v=q.top();q.pop();
flag[v.x]=;
for (int j=p[v.x];j;j=edge[j].nxt)
if (v.d+edge[j].len<d[edge[j].to])
{
d[edge[j].to]=v.d+edge[j].len;
q.push((data2){edge[j].to,d[edge[j].to]});
}
}
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
dis[start][i][j]=min(d[trans(i,j,)],d[trans(i,j,)]);
}
}
namespace maxflow
{
const int S=,T=;
int ans,p[N<<],d[N<<],q[N<<],cur[N<<],t;
struct data{int to,nxt,cap,flow;}edge[N*N<<];
void addedge(int x,int y,int z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
}
bool bfs()
{
memset(d,,sizeof(d));d[S]=;
int head=,tail=;q[]=S;
do
{
int x=q[++head];
for (int i=p[x];~i;i=edge[i].nxt)
if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
{
d[edge[i].to]=d[x]+;
q[++tail]=edge[i].to;
}
}while (head<tail);
return ~d[T];
}
int work(int k,int f)
{
if (k==T) return f;
int used=;
for (int i=cur[k];~i;i=edge[i].nxt)
if (d[k]+==d[edge[i].to])
{
int w=work(edge[i].to,min(edge[i].cap-edge[i].flow,f-used));
edge[i].flow+=w,edge[i^].flow-=w;
if (edge[i].flow<edge[i].cap) cur[k]=i;
used+=w;if (used==f) return f;
}
if (used==) d[k]=-;
return used;
}
void make(int lim)
{
t=-;memset(p,,sizeof(p));
for (int i=;i<=(k<<);i++) addedge(S,i,);
for (int i=;i<=l;i++) addedge((k<<)+i,T,w[v[i].x][v[i].y]);
for (int i=;i<=(k<<);i++)
for (int j=;j<=l;j++)
if (dis[i][v[j].x][v[j].y]<=lim) addedge(i,(k<<)+j,);
}
int dinic(int lim)
{
make(lim);
ans=;
while (bfs())
{
memcpy(cur,p,sizeof(p));
ans+=work(S,N);
}
return ans;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2547.in","r",stdin);
freopen("bzoj2547.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read(),k=read(),l=read();
for (int i=;i<=(k<<|);i++) u[i].x=read(),u[i].y=read();
for (int i=;i<=l;i++) v[i].x=read(),v[i].y=read(),w[v[i].x][v[i].y]=read();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
a[i][j]=read();
shortestpath::make();
for (int i=;i<=(k<<);i++) shortestpath::dijkstra(i);
int l=,r=k<<,ans;
while (l<=r)
{
int mid=l+r>>;
if (maxflow::dinic(mid)+mid>=(k<<)) ans=mid,r=mid-;
else l=mid+;
}
cout<<ans;
return ;
}

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. BZOJ 1570: [JSOI2008]Blue Mary的旅行( 二分答案 + 最大流 )

    二分答案, 然后对于答案m, 把地点分成m层, 对于边(u, v), 第x层的u -> 第x+1层的v 连边. 然后第x层的u -> 第x+1层的u连边(+oo), S->第一层的1 ...

  5. BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

    一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 ...

  6. BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

    题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连 ...

  7. HDU3081(KB11-N 二分答案+最大流)

    Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. Gym - 101908G 二分答案+最大流

    After the end of the truck drivers' strike, you and the rest of Nlogônia logistics specialists now h ...

  9. 紫书 习题 11-10 UVa 12264 (二分答案+最大流)

    书上写的是UVa 12011, 实际上是 12264 参考了https://blog.csdn.net/xl2015190026/article/details/51902823 这道题就是求出一种最 ...

随机推荐

  1. Ubuntu 中使用git 上传代码

    现在很多人都愿意把自己的代码分享给大家,所以有很多的代码管理的软件 ,比如SVN Git 等软件.今天就讲一下  git 的简单的应用,上传代码.用 git 上传代码 要有个git 账号,这是必不少的 ...

  2. 写脚本时出现: Permission denied

    例如对文件 remove.sh sudo chmod -R 777 remove.sh

  3. Java中的单利模式介绍

    单利模式:本来是不准备写的,但是最近发现好多公司面试时都会或多或少的提到单利模式,因此今天把单利模式拉出来说说. 定义:只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且 ...

  4. Swift图书展示项目笔记

    1.Swift语言特点 Extensions(扩展):就是向一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模) map: 得到一个 ...

  5. Docker中查看Mysql数据库中的各环境参数

    通过官方的文档可以看到运行MySQL容器的命令是: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mypwd -d mysql:tag 如:d ...

  6. [Baltic 2011]Lamp BZOJ2346

    分析: 建图最短路,比较裸. 我们可以考虑,如果是‘\’那么,左上连右下边权为0,左下连右上边权为1,反之亦然. 卡裸spfa,加点优化能过,我就直接改成的堆优化Dijkstra 附上代码: #inc ...

  7. 蜻蜓fm面试

    一面: 面试官首先看简历上写了在腾讯的实习,然后就探讨了半天,各种虚拟化的技术.... 说完之后,估计都半小时过去了,然后就又说了一下你用什么语言,你做的东西都比较偏底层呢,然后你对工作有什么要求吗? ...

  8. ccf201703-1分蛋糕

    问题描述 小明今天生日,他有n块蛋糕要分给朋友们吃,这n块蛋糕(编号为1到n)的重量分别为a1, a2, …, an.小明想分给每个朋友至少重量为k的蛋糕.小明的朋友们已经排好队准备领蛋糕,对于每个朋 ...

  9. currentBackgroundImage:获取按钮背景图片

    NSData *imagedata1=UIImagePNGRepresentation(btn.currentBackgroundImage);//按钮背景图片转NSData NSData *imag ...

  10. # 20155337《网络对抗》Exp9 Web安全基础

    20155337<网络对抗>Exp9 Web安全基础 实践目标 一.基础问题回答 1.实验后回答问题 SQL注入攻击原理,如何防御 SQL注入攻击的本质是利用SQL语法,针对应用程序开发过 ...