[xsy2213]tower
题意:给一个地图,地图上的每个位置是空地或一个炮或一些敌人,给定每个炮的方向(上/下/左/右),每个炮只能打一个位置且炮弹轨迹不能相交,问最多打到多少敌人
原题貌似是TC SRM 627的题,题解在这里
考虑一开始让每个炮都打敌人最多的位置,这样轨迹有可能相交,我们要做的就是合理规划,缩短某些炮击的距离使轨迹不相交的同时能打到的敌人减少量最少
对于水平炮,我们这样建图:

即:假设$y$是$x$往炮方向的第一个点,如果$x$的敌人数量比炮能打到的最多敌人数量少$v$,那么连边$(x,y,v)$
对于竖直炮,我们这样建图:

即:假设$x$是$y$往炮方向的第一个点,如果$y$的敌人数量比炮能打到的最多敌人数量少$v$,那么连边$(x,y,v)$
对于这个图的竖边,如果我们割掉$(x,y,v)$,那么就相当于让某个竖直炮打$y$,并且它比最优情况打少了$v$个敌人,横边类似
如果我们把竖直炮设为源点,水平炮设为汇点,那么因为不能相交,所以我们割掉一些边(决定了某些炮的打击目标)后,不能有任何一条从源点到汇点的路径,所以就相当于求最小割
这样还会有一个问题:我们要割掉先走竖边再走横边(炮弹轨迹不能相交),但是交错走横竖边是被允许的,所以我们还要从(竖边连接的点)向对应的(横边连接的点)连一条$+\infty$的边,确保先走竖再走横的路径会被割掉

所以最后的答案就是每个炮能打到的最多敌人数量加起来再减去最小割
#include<stdio.h>
#include<string.h>
const int inf=2147483647;
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
int h[5010],cur[5010],nex[30010],to[30010],cap[30010],q[30010],dis[5010],M=1,S,T;
void add(int a,int b,int c){
M++;
to[M]=b;
cap[M]=c;
nex[M]=h[a];
h[a]=M;
M++;
to[M]=a;
cap[M]=0;
nex[M]=h[b];
h[b]=M;
}
bool bfs(){
int x,i,head,tail;
head=tail=1;
q[1]=S;
memset(dis,-1,sizeof(dis));
dis[S]=0;
while(head<=tail){
x=q[head];
head++;
for(i=h[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==-1){
dis[to[i]]=dis[x]+1;
if(to[i]==T)return 1;
tail++;
q[tail]=to[i];
}
}
}
return 0;
}
int dfs(int x,int flow){
if(x==T)return flow;
int i,f;
for(i=cur[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==dis[x]+1){
f=dfs(to[i],min(flow,cap[i]));
if(f){
cap[i]-=f;
cap[i^1]+=f;
if(cap[i])cur[x]=i;
return f;
}
}
}
dis[x]=-1;
return 0;
}
int dicnic(){
int ans=0,tmp;
while(bfs()){
memcpy(cur,h,sizeof(h));
while(tmp=dfs(S,100000000))ans+=tmp;
}
return ans;
}
int n,m,s[60][60],tmp[60];
const int go[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
bool ok(int x,int y){return 0<x&&x<=n&&0<y&&y<=m;}
int ve(int x,int y){return(x-1)*m+y;}
int ho(int x,int y){return(x-1)*m+y+n*m;}
void move(int&x,int&y,int f){
x+=go[f][0];
y+=go[f][1];
}
int main(){
int i,j,x,y,f,cnt,sum,mx;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)scanf("%d",s[i]+j);
}
S=n*m*2+1;
T=n*m*2+2;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)add(ve(i,j),ho(i,j),inf);
}
sum=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(s[i][j]<0){
x=i;
y=j;
f=-s[i][j]-1;
cnt=0;
while(ok(x,y)){
cnt++;
tmp[cnt]=max(tmp[cnt-1],s[x][y]);
move(x,y,f);
}
mx=tmp[cnt];
sum+=mx;
move(x,y,f^1);
while(x!=i||y!=j){
cnt--;
if(f<2)
add(ve(x-go[f][0],y-go[f][1]),ve(x,y),mx-tmp[cnt]);
else
add(ho(x,y),ho(x-go[f][0],y-go[f][1]),mx-tmp[cnt]);
move(x,y,f^1);
}
if(f<2)
add(S,ve(i,j),inf);
else
add(ho(i,j),T,inf);
}
}
}
printf("%d",sum-dicnic());
}
[xsy2213]tower的更多相关文章
- Tower是个不错的项目管理开放平台
简单,易用,轻量级,挺多大项目都在用. 目前公司的项目也在使用,但是从高层到底下,随意惯了,最终没有用起来. 感觉适合年轻激情的创业公司团队来使用. 附上地址:https://tower.im/
- dwarf tower
dwarf tower(dwarf.cpp/c/pas)[问题描述]Vasya在玩一个叫做"Dwarf Tower"的游戏,这个游戏中有n个不同的物品,它们的编号为1到n.现在Va ...
- HDU1329 Hanoi Tower Troubles Again!——S.B.S.
Hanoi Tower Troubles Again! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- ZOJ-1239 Hanoi Tower Troubles Again!
链接:ZOJ1239 Hanoi Tower Troubles Again! Description People stopped moving discs from peg to peg after ...
- Ansible-Tower快速入门-6.查看tower的仪表板【翻译】
查看tower的仪表板 到这一步,我们已经可以在屏幕上看到tower的仪表板了,我们可以看到你目前"主机""资产清单"和"项目"的汇总信息, ...
- 自动运维:Ansible -ansible tower
文档主页:http://docs.ansible.com/参考文档:http://docs.ansible.com/ansible/参考文档:http://docs.ansible.com/ansib ...
- dp --- hdu 4939 : Stupid Tower Defense
Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- 塔吊力矩限制器,塔吊黑匣子,塔吊电脑,tower crane
塔机力矩限制器,tower crane 适用于各种类型的固定臂塔机和可变臂塔机 塔机力矩限制器是塔式起重机机械的安全保护装置,本产品采用32位高性能微处理器为硬件平台,软件算法采用国内最先进的三滑轮取 ...
- UVa 437 The Tower of Babylon(经典动态规划)
传送门 Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details ...
随机推荐
- Pytest 断言
pytest 断言 断言:一个标准的用例都包含了断言,编写pytest自动化脚本的时候,也需要设置断言 assert使用 常用分三种 1:比较大小与是否相等 2:包含或不包含 3:验证boolean ...
- 更改maven本地仓库地址
1.进入maven安装conf文件中,编辑settings.xml文件,新增图中的圈出的内容(我想要存放的地址是D:\HMY\m2\repository) 2.复制settings.xml文件至D:\ ...
- bash 语言的乘法表
#!/bin/bash ];then exit fi ; i<$; i++)); do ; j<=i; j++)); do tput setaf $j echo -ne "$j& ...
- ASP.NET Core API ---状态码
摘录自:https://www.cnblogs.com/cgzl/p/9047626.html 状态码是非常重要的,因为只有状态码会告诉API的消费者: 请求是否如预期的成功,或者失败 如果出现了错误 ...
- 我与0xc000007b奋斗的日子
自从新换了一台笔记本,就开始重装各种软件,就在将要开始软工课设的重要的日子里,我默默地在运行客户端时出现了一个这样的错误: 鉴于本人很废柴,自然不可能去查内存,所以开始各种度娘必应和谷歌,哦!原来应该 ...
- BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】
题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...
- php5.3.3以上重启php-fpm的方法
http://www.cnblogs.com/GaZeon/p/5421906.html
- navicat for mysql 2003错误
最近又一次碰到navicat for mysql 2003错误,之前碰到好几次了,问题再次出现还是有些不知所措,所以记下来,再次遇到时就可以迎韧有余了. 解决方案1: 重启防火墙:关闭再重新开启. 解 ...
- 解决hibernate向mysql插入中文乱码问题(更改MySQL字符集)
1.首先需要修改mysql数据库的配置文件my.ini,此文件放在mysql根目录下.在此文件下查找default-character-set属性,并将其值更改为utf8(注意:不是utf-8,也要注 ...
- ClientScript.RegisterClientScriptBlock 不执行
ClientScript.RegisterClientScriptBlock 不执行 页面中 form标签必须加入 runat=server