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的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  3. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  4. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  5. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

  6. NOI2019省选模拟赛 第六场

    传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...

  7. 省选模拟赛 arg

    1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...

  8. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

  9. 5.5 省选模拟赛 B Permutation 构造 贪心

    LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...

随机推荐

  1. React Native 之 main.jsbundle生成方法

    通过react-native init yooweiProject 生成的RN项目(版本基于0.57),目录结构如下 项目结构: 大家可以发现main.jsbundle 是红色的,不存在的,这个属于正 ...

  2. CF 1095C Powers Of Two(二进制拆分)

    A positive integer xx is called a power of two if it can be represented as x=2y, where y is a non-ne ...

  3. 探路者-Beta发布中间产物

    版本控制 版本控制报告:http://www.cnblogs.com/linym762/p/7881047.html git地址:https://git.coding.net/clairewyd/to ...

  4. json转对象

    1,引入依赖 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib& ...

  5. 第一次spring冲刺第6天

    鉴于昨天的调查,今天做了个谈论,主要针对以下几个问题 1.我们的客户类型? 2.如何实现他们的需求? 3.他们真正想要什么? 4.如何保证他们的满足度? 5.怎么使得工程不陷入死循环? 6.还存在什么 ...

  6. 单调队列(数列中长度不超过k的子序列和的最值)

    ★实验任务 小 F 很爱打怪,今天因为系统 bug,他提前得知了 n 只怪的出现顺序以及击 倒每只怪得到的成就值 ai.设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒 钟出现一只新怪且没被击倒 ...

  7. grunt入门讲解6:grunt使用步骤和总结

    Grunt是啥? 很火的前端自动化小工具,基于任务的命令行构建工具. Grunt能帮我们干啥? 假设有这样一个场景: 编码完成后,你需要做以下工作 HTML去掉注析.换行符 - HtmlMin CSS ...

  8. HDU 2134 Cuts the cake

    http://acm.hdu.edu.cn/showproblem.php?pid=2134 Problem Description Ice cream took a bronze medal in ...

  9. Excel中用REPT函数制作图表

    本文从以下七个方面,阐述在Excel中用REPT函数制作图表: 一. 图形效果展示 二. REPT语法解释 三. REPT制作条形图 四. REPT制作漏斗图 五. REPT制作蝴蝶图 六. REPT ...

  10. windows多线程(十一) 更安全的创建线程方式_beginthreadex()

    一.原因分析 CreateThread()函数是Windows提供的API接口,在C/C++语言另有一个创建线程的函数_beginthreadex(),我们应该尽量使用_beginthreadex() ...