P3866 [TJOI2009]战争游戏
P3866 [TJOI2009]战争游戏
题目背景
小R正在玩一个战争游戏。游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中。每支敌军都可以从当前所在的格子移动到四个相邻的格子之一,但是不能移动到包含障碍物的格子。如果敌军移动出了地图的边界,那么战争就失败了。
题目描述
现在你的任务是,在敌军开始移动前,通过飞机轰炸使得某些原本是空地的格子变得不可通行,这样就有可能阻止敌军移出地图边界(出于某种特殊的考虑,你不能直接轰炸敌军所在的格子)。由于地形不同的原因,把每个空地格子轰炸成不可通行所需的炸弹数目可能是不同的,你需要计算出要阻止敌军所需的最少的炸弹数。
输入输出格式
输入格式:
输入文件的第一行包含两个数M和N,分别表示矩阵的长和宽。接下来M行,每行包含用空格隔开的N个数字,每个数字表示一个格子的情况:若数字为-1,表示这个格子是障碍物;若数字为0,表示这个格子里有一支敌军;若数字为一个正数x,表示这个格子是空地,且把它轰炸成不可通行所需的炸弹数为x。
输出格式:
输出一个数字,表示所需的最少炸弹数。数据保证有解存在。
挺裸的最小割模型: 炸掉一个点 = 割掉一条边
这条关键边要放在哪呢? 一个点被炸掉了以后, 这个点再也不能通过, 联想到将点分裂为两个, 关建边容量为摧毁炸弹数连接这两个点。
所以我们做如下连边:
对于一点 \(x\) , 若是起点, 则连接源点与 \(x\) ,容量为 \(INF\) , 再连接 \(x\) 与 \(x'\) 代表此点无法被轰炸
若是路障, 则连接 \(x\) 与 \(x'\) 容量为 \(0\) , 表示此点不需要炸弹也走不通(即需要炸弹数为 \(0\) )
其余则连接 \(x\) 与 \(x'\) 容量为轰炸所需炸弹数即可
对于相连的两点, 连接出点与入点, 容量为 \(INF\)
对于边缘点, 连接出点与汇点, 容量为 \(INF\)
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
typedef long long LL;
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 1000019,INF = 1e9 + 19;
int head[maxn],nume = 1;
struct Node{
int v,dis,nxt;
}E[maxn << 3];
void add(int u,int v,int dis){
E[++nume].nxt = head[u];
E[nume].v = v;
E[nume].dis = dis;
head[u] = nume;
}
int maxflow, s, t;
int d[maxn];
bool bfs(){
queue<int>Q;
memset(d, 0, sizeof(d));
d[s] = 1;
Q.push(s);
while(!Q.empty()){
int u = Q.front();Q.pop();
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(!d[v] && E[i].dis)d[v] = d[u] + 1, Q.push(v);
if(v == t)return 1;
}
}
return 0;
}
int Dinic(int u, int flow){
if(u == t)return flow;
int rest = flow, k;
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(d[v] == d[u] + 1 && E[i].dis){
k = Dinic(v, min(rest, E[i].dis));
if(!k)d[v] = 0;
E[i].dis -= k;
E[i ^ 1].dis += k;
rest -= k;
}
if(!rest)break;
}
return flow - rest;
}
int lenx, leny;
int mx[4] = {0 ,0, 1,-1};
int my[4] = {1,-1, 0, 0};
int map[119][119];
int id(int x, int y){return (x - 1) * leny + y;}
bool judge(int x, int y){
if(x < 1 || x > lenx || y < 1 || y > leny)return 0;
return 1;
}
int main(){
lenx = RD();leny = RD();
s = 0, t = 10026;
for(int i = 1;i <= lenx;i++)for(int j = 1;j <= leny;j++)map[i][j] = RD();
for(int i = 1;i <= lenx;i++)for(int j = 1;j <= leny;j++){
int u = id(i, j);
if(!map[i][j]){
add(s, u << 1, INF), add(u << 1, s, 0);
add(u << 1, u << 1 | 1, INF), add(u << 1 | 1, u << 1, 0);
}
else if(map[i][j] == -1)add(u << 1, u << 1 | 1, 0), add(u << 1 | 1, u << 1, 0);
else add(u << 1, u << 1 | 1, map[i][j]), add(u << 1 | 1, u << 1, 0);
for(int k = 0 ;k < 4;k++){
int nx = i + mx[k];
int ny = j + my[k];
int v = id(nx, ny);
if(judge(nx, ny)){
add(u << 1 | 1, v << 1, INF);
add(v << 1, u << 1 | 1, 0);
}
else add(u << 1 | 1, t, INF), add(t, u << 1 | 1, 0);
}
}
int flow = 0;
while(bfs())while(flow = Dinic(s, INF))maxflow += flow;
printf("%d\n", maxflow);
return 0;
}
P3866 [TJOI2009]战争游戏的更多相关文章
- P3866 [TJOI2009]战争游戏 最小割
$ \color{#0066ff}{ 题目描述 }$ 小R正在玩一个战争游戏.游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中.每支敌军 ...
- [TJOI2009] 战争游戏
题目背景 小R正在玩一个战争游戏.游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中.每支敌军都可以从当前所在的格子移动到四个相邻的格子之 ...
- 「Luogu P3866」[TJOI2009]战争游戏 解题报告
题面 好难表述啊~ 在n*m的矩阵上,有一些大兵(为0),一些空地(一个正整数),障碍物(-1),现在摧毁一些空地,使所有大兵不能走出矩阵去(代价为表示空地的整数),求最小代价 思路: 网络流最小割 ...
- 战争游戏(War Games 1983)剧情
战争游戏 War Games(1983) 人工控制导弹发射 傍晚大雾,两值工作人员自驾一辆轿车到达监控俄罗斯核战争的防空基地,在门口出示工作证后进入基地,两工作人员和同事换班后,进入防空系统控制室开始 ...
- 魔兽争霸RPG游戏-军团战争-游戏经验总结
终于要写这篇了,上一篇是个意外. 2015年关注,一代鬼王Xun和GGL比赛.晚上11点之后,经常有水友赛.主播xun,会带着一帮小弟,玩一些游戏.比如魔兽争霸6v6,2v2,RPG游戏-军团战争,疯 ...
- Python开发项目:大型模拟战争游戏(外星人入侵)
外星人入侵 游戏概述: 现在准备用python开始搞一个大型游戏,模拟未来战争,地球人狙击外星人大战(其实就是小蜜蜂游戏2333),玩家控制一个飞船,用子弹歼灭屏幕上空的外星飞船:项目用到了Pygam ...
- Python开发【项目】:大型模拟战争游戏(外星人入侵)
外星人入侵 游戏概述: 现在准备用python开始搞一个大型游戏,模拟未来战争,地球人狙击外星人大战(其实就是小蜜蜂游戏2333),玩家控制一个飞船,用子弹歼灭屏幕上空的外星飞船:项目用到了Pygam ...
- 战争游戏OverTheWire:Bandit(一)
一个用来熟悉linux命令的游戏: Level0 告诉我们使用ssh连接网址,用户名和密码皆为bandit0.使用Xshell或者linux连接都可以 我使用的是Xshell5: Level0-> ...
- 3896. 【NOIP2014模拟10.26】战争游戏
鉴于如此一道恶心的题,作者还花了一个晚上草草学了tarjan. 于是乎,这道题就是道tarjan 具体怎么实现呢?正解上有个什么树形DP,看的我一脸懵逼. 这道题可以运用到tarjan一个高科技的算法 ...
随机推荐
- TeamWork#3,Week5,Scrum Meeting 11.13
最近我们根据之前发现的问题, 补充了相关知识,正在努力修复出现的问题,调整程序结构. 成员 已完成 待完成 彭林江 之前没有考虑到网站信息更新导致的程序可变性,正在调整爬虫程序结构 更换爬虫结构 郝倩 ...
- 实验五Java网络编程及安全
实验五 Java网络编程及安全 结对伙伴:20135231林涵锦(负责服务器方)http://www.cnblogs.com/20135213lhj/ 实验目的与要求: 1.掌握Java网络编程的方 ...
- 20172321『Java程序设计』课程 结对编程练习_四则运算第二周阶段总结
20172321『Java程序设计』课程 结对编程练习_四则运算第二周阶段总结 结对伙伴 学号 :20172324 姓名 :曾程 伙伴第一周博客地址: 对结对伙伴的评价:一个很优秀的同学,在这次项目中 ...
- Task 5.1 电梯调度程序需求调研报告
1.任务概述: 1.1任务背景:试想一下,石家庄铁道大学基础教学楼的电梯配置如下:大厦有18层, 4部电梯,很多乘客使用这些电梯的日常(旅客重量:平均70公斤最大120公斤,最小45公斤).其他常量数 ...
- Math 类的使用(一小部分)
package com.Date.Math; /* Math 数学类, 主要是提供了很多的数学公式. abs(double a) 获取绝对值 ceil(double a) 向上取整 floor(dou ...
- ASP.NET Forms身份验证概述
表单身份验证允许您使用自己的代码对用户进行身份验证,然后在cookie或页面URL中维护身份验证令牌.表单身份验证通过FormsAuthenticationModule类参与ASP.NET页面生命周期 ...
- Head First Java & 异常
- 微信小程序之Flex布局
微信小程序页面布局方式采用的是Flex布局.Flex布局,是W3c在2009年提出的一种新的方案,可以简便,完整,响应式的实现各种页面布局.Flex布局提供了元素在容器中的对齐,方向以及顺序,甚至他们 ...
- 由一个滑动条的任务需求产生一个对UISlider控件的探讨
任务需求样式:
- Oracle中创建自增字段方法
oracle没有ORACLE自增字段这样的功能,但是通过触发器(trigger)和序列(sequence)可以实现. 下面给大家讲个例子: 1.在Oracle中创建一个表: .创建一个表 ) prim ...