省选模拟赛 cti
3 cti (cti.cpp/in/out, 1s, 512MB)
3.1 Description
有一个 n × m 的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭
敌人.
对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它的攻击位置,
当然也可以不进行攻击. 一旦一个位置被攻击, 则在这个位置上的所有敌人都会被消灭.
保证对于任意一个炮塔, 它所有可能的攻击位置上不存在另外一个炮塔.
定义炮弹的运行轨迹为炮弹的起点和终点覆盖的区域. 你需要求出一种方案, 使得没有两条炮
弹轨迹相交.
3.2 Input Format
第一行两个整数 n,m.
接下来 n 行, 每行 m 个整数, 0 表示空地, −1,−2,−3,−4 分别表示瞄准上下左右的炮塔, 正整
数 p 表示表示此位置有 p 个敌人.
3.3 Output Format
一行一个整数表示答案.
3.4 Sample 1
3.4.1 Input
3 2
0 9
-4 3
0 -1
3.4.2 Output
9
3.5 Sample 2
3.5.1 Input
4 5
0 0 -2 0 0
-4 0 5 4 0
0 -4 3 0 6
9 0 0 -1 0
3.5.2 Output
12
3.6 Constraints
对于前 20% 的数据, n,m ≤ 5;
对于另 20% 的数据, 朝向上下的炮塔至多有 2 个;
对于另 20% 的数据, 至多有 6 个炮塔;
对于 100% 的数据, 1 ≤ n,m ≤ 50, 每个位置的敌人数量 < 1000.
分析:将题目看作炮塔和敌人“匹配”,就和比特板这道题几乎一模一样了.
需要注意的是炮塔可以不攻击任何敌人,那么连inf的边实际上就是连0边.
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = * ,inf = 0x7fffffff;
int n,m,ans,a[][],cnt,cnt1,cnt2,S,T,pos[maxn][maxn],head[],to[],nextt[],w[],tot = ;
int d[];
struct node
{
int x,y,opt;
} shu[maxn],heng[maxn]; void add(int x,int y,int z)
{
//cout << x << " " << y << " " << 1000 - z << endl;
w[tot] = z;
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++; w[tot] = ;
to[tot] = x;
nextt[tot] = head[y];
head[y] = tot++;
} bool bfs()
{
queue <int> q;
q.push(S);
memset(d,-,sizeof(d));
d[S] = ;
while (!q.empty())
{
int u = q.front();
q.pop();
if (u == T)
return true;
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (w[i] && d[v] == -)
{
d[v] = d[u] + ;
q.push(v);
}
}
}
return false;
} int dfs(int u,int f)
{
if (u == T)
return f;
int res = ;
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (d[v] == d[u] + && w[i])
{
int temp = dfs(v,min(f - res,w[i]));
w[i] -= temp;
w[i ^ ] += temp;
res += temp;
if (res == f)
return res;
}
}
if (!res)
d[u] = -;
return res;
} void dinic()
{
while (bfs())
ans -= dfs(S,inf);
} int main()
{
scanf("%d%d",&n,&m);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
{
scanf("%d",&a[i][j]);
if (a[i][j] < )
{
if (a[i][j] == - || a[i][j] == -)
{
node temp;
temp.x = i;
temp.y = j;
temp.opt = a[i][j];
shu[++cnt1] = temp;
}
else
{
node temp;
temp.x = i;
temp.y = j;
temp.opt = a[i][j];
heng[++cnt2] = temp;
}
}
}
for (int i = ; i <= cnt1; i++)
{
if (shu[i].opt == -)
for (int j = ; j <= shu[i].x; j++)
pos[i][j] = ++cnt;
else
for (int j = ; j <= n - shu[i].x + ; j++)
pos[i][j] = ++cnt;
}
for (int i = ; i <= cnt2; i++)
{
if (heng[i].opt == -)
for (int j = ; j <= heng[i].y; j++)
pos[i + cnt1][j] = ++cnt;
else
for (int j = ; j <= m - heng[i].y + ; j++)
pos[i + cnt1][j] = ++cnt;
}
ans = * (cnt1 + cnt2);
S = ++cnt;
T = ++cnt;
for (int i = ; i <= cnt1; i++)
{
if (shu[i].opt == -)
{
for (int j = ; j <= shu[i].x; j++)
{
if (j != shu[i].x)
add(pos[i][j],pos[i][j + ], - a[shu[i].x - j][shu[i].y]);
else
add(pos[i][j],T,);
if (j == )
add(S,pos[i][j],);
}
}
else
{
for (int j = ; j <= n - shu[i].x + ; j++)
{
if (j != n - shu[i].x + )
add(pos[i][j],pos[i][j + ], - a[shu[i].x + j][shu[i].y]);
else
add(pos[i][j],T,);
if (j == )
add(S,pos[i][j],);
}
}
}
for (int i = ; i <= cnt2; i++)
{
if (heng[i].opt == -)
{
for (int j = ; j <= heng[i].y; j++)
{
if (j != heng[i].y)
add(pos[i + cnt1][j],pos[i + cnt1][j + ], - a[heng[i].x][j]);
else
add(pos[i + cnt1][j],T,);
if (j == )
add(S,pos[i + cnt1][j],);
}
}
else
{
for (int j = ; j <= m - heng[i].y + ; j++)
{
if (j != m - heng[i].y + )
add(pos[i + cnt1][j],pos[i + cnt1][j + ], - a[heng[i].x][m - j + ]);
else
add(pos[i + cnt1][j],T,);
if (j == )
add(S,pos[i + cnt1][j],);
}
}
}
for (int i = ; i <= cnt1; i++)
for (int j = ; j <= cnt2; j++)
{
int X,Y;
if (shu[i].opt == - && heng[j].opt == -) //上右
{
if (shu[i].x < heng[j].x || shu[i].y < heng[j].y)
continue;
X = heng[j].x;
Y = shu[i].y;
int temp1 = shu[i].x - X;
int temp2 = m - Y + ;
add(pos[i][temp1],pos[j + cnt1][temp2],);
}
if (shu[i].opt == - && heng[j].opt == -) //上左
{
if (shu[i].x < heng[j].x || shu[i].y > heng[j].y)
continue;
X = heng[j].x;
Y = shu[i].y;
int temp1 = shu[i].x - X;
int temp2 = Y + ;
add(pos[i][temp1],pos[j + cnt1][temp2],);
}
if (shu[i].opt == - && heng[j].opt == -) //下右
{
if (shu[i].y < heng[j].y || shu[i].x > heng[j].x)
continue;
X = heng[j].x;
Y = shu[i].y;
int temp1 = X - shu[i].x;
int temp2 = m - Y + ;
add(pos[i][temp1],pos[j + cnt1][temp2],);
}
if (shu[i].opt == - && heng[j].opt == -) //下左
{
if (shu[i].x > heng[j].x || shu[i].y > heng[j].y)
continue;
X = heng[j].x;
Y = shu[i].y;
int temp1 = X - shu[i].x;
int temp2 = Y + ;
add(pos[i][temp1],pos[j + cnt1][temp2],);
}
}
dinic();
printf("%d\n",ans); return ;
}
省选模拟赛 cti的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- @省选模拟赛03/16 - T3@ 超级树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...
- 3.28 省选模拟赛 染色 LCT+线段树
发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...
- 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)
一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...
- NOI2019省选模拟赛 第五场
爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...
- NOI2019省选模拟赛 第六场
传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...
- 省选模拟赛 arg
1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...
- 5.10 省选模拟赛 拍卖 博弈 dp
LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...
- 5.5 省选模拟赛 B Permutation 构造 贪心
LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...
随机推荐
- cal命令详解
基础命令学习目录首页 原文链接:https://www.yiibai.com/linux/cal.html cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳 ...
- which命令详解
基础命令学习目录首页 原文链接:https://www.cnblogs.com/jkin/p/10289085.html Linux which命令用于查找文件. which指令会在环境变量$PATH ...
- HDFS handler
http://docs.oracle.com/goldengate/bd1221/gg-bd/GADBD/GUID-85A82B2E-CD51-463A-8674-3D686C3C0EC0.htm#G ...
- LeetCode 561. Array Partition I (C++)
题目: Given an array of 2n integers, your task is to group these integers into npairs of integer, say ...
- 冲刺One之站立会议4 /2015-5-17
今天我们继续了昨天未完成的部分,把服务器端的在线人数显示做了出来,但是在调试的时候还有一些不可预知的自己也不会改的bug,让我们有点不知所措,启动时间的显示相对来说比较容易实现. 燃尽图4
- lintcode-514-栅栏染色
514-栅栏染色 我们有一个栅栏,它有n个柱子,现在要给柱子染色,有k种颜色可以染. 必须保证不存在超过2个相邻的柱子颜色相同,求有多少种染色方案. 注意事项 n和k都是非负整数 样例 n = 3, ...
- Swift-KVC构造函数中数据类型和私有属性
- 转 webpack 插件 svg-sprite-loader
最近开始看 Vue 了,首先用官方的模版把项目快速搭建起来: Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用.该工具提供开箱即用的构建工具配置,带来现代化的前端开发流程.只需几分钟即 ...
- python 菜鸟入门
python 菜鸟博客: http://www.cnblogs.com/wupeiqi/articles/5433893.html http://www.cnblogs.com/linhaifeng/ ...
- build.xml
下载ant 解压ant 后设置ANT_HOME, PATH中添加ANT_HOME目录下的bin目录(如:ANT_HOME:,PATH:D:\apache-ant-1.9.2%ANT_HOME%\bin ...