省选模拟赛 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 ...
随机推荐
- 关于SQL while 循环嵌套 外部循环数据无法进入内部循环
下面一般是,作为SQL新手第一次写循环嵌套的办法,但是大家会发现一个问题,那就是变量@i总是不能进入第二个循环. declare @i int ,@j int, @k int set @j = 1 - ...
- iOS静默推送(Silent Remote Notifications)
此功能是iOS7新增加的功能,允许应用收到通知后在后台(background)状态下运行一段代码,可用于从服务器获取内容更新. 普通推送:收到推送后(有文字有声音),点开通知,进入APP后,才执行-- ...
- 【转】git乱码解决方案汇总
git乱码解决方案汇 2012-11-04更新:官方的“终极”解决方案:msysGit1.7.10开始使用UTF-8编码保存文件名. 2011-10-24更新: 从一篇链接到本篇文章的文章(我对这篇文 ...
- JavaWeb项目通过调用cmd实现备份数据库的功能
1.别急着上车,先测试一下能否成功调用cmd,可以尝试通过cmd命令打开计算器,代码如下: 2.能成功打开计算器后,证明调用cmd的方法是没错的,现在把cmd命令字符串改成我们备份数据库的 命 ...
- Scrum Meeting 10.31
成员 今日任务 明日任务 今日工作时长 徐越 整理开发文档,学习ip相关知识,学习servlet相关知识 代码迁移,学习数据库相关知识 5h 赵庶宏 学习学长的servlet代码 进行数据库的连接 4 ...
- iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能
类似微信聊天消息中的电话号码点击保存到通讯录中的功能,ABAddress的实现在iOS9中是不能正常使用的,点击完成后,手机会非常的卡,iOS9之后需要使用Contact新提供的方法来实现该功能.快捷 ...
- [不明所以]android 5.0 couldn't find "libmsc.so"
用5.0 mi2调试的时候 search那边不行, 出现...couldn't find "libmsc.so" 我这边情况的解决方法是 在armeabi的libmsc.so复制一 ...
- 51单片机,keilc51,如何使用data变量超过128怎么办
将堆栈指针SP指向128之后.如果你定义了数组.将数组定义为Idata.很难想象单个变量使用,你能用尽128个data类内存单元.如果真的用尽了,那只有将访问频率低的内存单元放到idata类去.总之, ...
- charles抓取移动端app数据
pc端为mac 移动端为android pc端 1.下载charles并安装 安利一个超好的良心网站(好多好用的软件都可以在上面找到,并且免费): http://xclient.info/search ...
- Beta阶段冲刺前的准备
Beta阶段冲刺前的准备 凡事预则立,在Beta开始前,以小组为单位,在敏捷冲刺前发布一篇博客,描述: 1. 讨论组长是否重选的议题和结论 经过我们小组在周二下午的会议中有重新认真的考虑了是否要更换组 ...