题意:给一个地图,地图上的每个位置是空地或一个炮或一些敌人,给定每个炮的方向(上/下/左/右),每个炮只能打一个位置且炮弹轨迹不能相交,问最多打到多少敌人

原题貌似是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的更多相关文章

  1. Tower是个不错的项目管理开放平台

    简单,易用,轻量级,挺多大项目都在用. 目前公司的项目也在使用,但是从高层到底下,随意惯了,最终没有用起来. 感觉适合年轻激情的创业公司团队来使用. 附上地址:https://tower.im/

  2. dwarf tower

    dwarf tower(dwarf.cpp/c/pas)[问题描述]Vasya在玩一个叫做"Dwarf Tower"的游戏,这个游戏中有n个不同的物品,它们的编号为1到n.现在Va ...

  3. 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 ...

  4. ZOJ-1239 Hanoi Tower Troubles Again!

    链接:ZOJ1239 Hanoi Tower Troubles Again! Description People stopped moving discs from peg to peg after ...

  5. Ansible-Tower快速入门-6.查看tower的仪表板【翻译】

    查看tower的仪表板 到这一步,我们已经可以在屏幕上看到tower的仪表板了,我们可以看到你目前"主机""资产清单"和"项目"的汇总信息, ...

  6. 自动运维:Ansible -ansible tower

    文档主页:http://docs.ansible.com/参考文档:http://docs.ansible.com/ansible/参考文档:http://docs.ansible.com/ansib ...

  7. dp --- hdu 4939 : Stupid Tower Defense

    Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  8. 塔吊力矩限制器,塔吊黑匣子,塔吊电脑,tower crane

    塔机力矩限制器,tower crane 适用于各种类型的固定臂塔机和可变臂塔机 塔机力矩限制器是塔式起重机机械的安全保护装置,本产品采用32位高性能微处理器为硬件平台,软件算法采用国内最先进的三滑轮取 ...

  9. UVa 437 The Tower of Babylon(经典动态规划)

    传送门 Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details ...

随机推荐

  1. 孤荷凌寒自学python第二十二天python类的继承

    孤荷凌寒自学python第二十二天python类的继承 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) python中定义的类可以继承自其它类,所谓继承的概念,我的理解 是,就是一个类B继承自 ...

  2. ssh.sh_for_ubuntu1604

    #!/bin/bash sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config ...

  3. 游戏开发学习ing

    创建工程 python cocos.py new HelloWorld -p com.cocos2dx.org -l cpp -d myprojects 这个命令就是运行python然后编译cos.p ...

  4. Could not automatically select an Xcode project. Specify one in your Podfile like so

    需要将Podfile文件放置在根目录下,而不能放置在项目的里面. 更改路径即可

  5. SQL查询oracle的nclob字段

    使用CONTAINS关键字查询NCLOB字段 SELECT  FORMATTED_MESSAGE    FROM     TBL_LOG WHERE     CONTAINS(FORMATTED_ME ...

  6. gulp-API介绍

    使用gulp,一般只需要用4个API:gulp.src(),gulp.dest(),gulp.task(),gulp.watch(). 1. gulp.src() 用来获取流的,但是要注意的是这个流里 ...

  7. [codeforces] 585D Lizard Era: Beginning || 双向dfs

    原题 有n(n<=2)个任务和三个人,每次任务给出每个人能得到的值,每次任务选两个人,使n个任务结束后三个人得到的值是一样的.输出每次要派哪两个人,如果不行输出Impossible. n< ...

  8. 洛谷 P4883 mzf的考验 解题报告

    P4883 mzf的考验 题目背景 \(mzf\)立志要成为一个豪杰,当然,他也是一个\(OIer\). 他希望自己除了会\(OI\)之外还会各种东西,比如心理学.吉他.把妹等等. 为了让自己有更大的 ...

  9. Java正则表达式--Matcher.group函数的用法

    原来,group是针对()来说的,group(0)就是指的整个串,group(1) 指的是第一个括号里的东西,group(2)指的第二个括号里的东西. 最近学习正则表达式,发现Java中的一些术语与其 ...

  10. HDU 1153 magic bitstrings(读题+)

    hdu 1153 magic bitstrings 题目大意 一个质数p,现在让你求一个p-1长度的“01魔法串”.关于这个魔法串是这么定义的:     我们现在把这个串经过一段处理变成一个长宽均为p ...