[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 ...
随机推荐
- 孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase
孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase (完整学习过程屏幕记录视频地址在文末) 之前对关系型数据库的学习告一段落,虽然能力所限没有能够完全完成理想中的所有数据库操 ...
- matlab使用摄像头人脸识别
#关于matlab如何读取图片.视频.摄像头设备数据# 参见:http://blog.csdn.net/u010177286/article/details/45646173 但是,关于摄像头读取,上 ...
- wireshark简单使用
过滤表达式的规则 表达式规则 1. 协议过滤 比如TCP,只显示TCP协议. ip.src == 219.216.87.200 and ip.dst==219.216.87.254 2 ...
- iOS 实现设备应用之间的相互切换
今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...
- winform 使用Anchor属性进行界面布局
每个控件的定位方法: 一.使用Anchor: Anchor分为Left.Top.Right.Bottom四个属性. 它们的含义如下: Top——表示控件中与父窗体(或父控件)相关的顶部应该保持固定. ...
- J2EE的十三种技术——JNDI
背景: 上一篇博客中介绍了J2EE的十三种技术之一--JDBC,主要用于提供了统一访问多种数据库的方式.这篇文章我们继续介绍J2EE的技术--JNDI. JNDI: Java Naming and D ...
- [洛谷P4389]付公主的背包
题目大意:有$n(n\leqslant10^5)$种物品,第$i$个物品体积为$v_i$,都有$10^5$件.给定$m(m\leqslant10^5)$,对于$s\in [1,m]$,请你回答用这些商 ...
- [bzoj] 1043 下落的圆盘 || 圆上的“线段覆盖”
原题 n个圆盘,求下落后能看到的总周长. 红色即为所求 借鉴于黄学长的博客 对于每下落的一个圆盘,处理他后面的圆盘会挡住哪些区域,然后把一整个圆(2\(/pi\))当做一整个区间,每个被覆盖的部分都可 ...
- 【转发】Build Squid with SSL Bump and ICAP Client
原文文档:http://docs.diladele.com/administrator_guide_3_4/installation_and_removal/filtering_https.html ...
- java8 获取对象中满足条件的金额之和
记录一个小笔记:获取一个对象中,支付成功的金额之和: Long sum = list.stream().filter(o -> o.getStatus() == SUCCESS).mapToLo ...