坚决抵制长题面的题目!

首先观察到这个题目中,我们会发现,我们对于原图中的保护关系(一个点右边的点对于这个点也算是保护)

相当于一种依赖。

那么不难看出这个题实际上是一个最大权闭合子图模型。

我们直接对于权值为负数的边,\(S\rightarrow now\),流量是\(-a[i][j]\),表示打掉他要花这么多的代价。

对于权值为正的边,\(now \rightarrow T\) ,流量是\(a[i][j]\),表示如果割掉这个边,表示放弃他的收益。

(这里之所以\(S和T\)不能反过来,因为我们跑最小割的时候,是要保证S到T不连通,所以你要让负的权值与S相连,才会让依赖关系有意义)

对于每个点,向他保护的点连边,边权为\(inf\)。表示这个关系不能打破。

同时一个点右边的点,向这个点连边,流量也是\(inf\),因为右边的点要比左边的点先被打。

最后的答案就是\(正权值的sum - 最小割\)(总的收益,减去花费和舍去的。)

那么建出来图,我们会发现其实这个是有问题的。

因为可能存在环的情况。

(\(A保护B,B保护A\))

那么应该怎么办呢?

我们发现如果存在一个环,那么环能保护到的点,以及再往后的点,都是无敌的!

所以合法的点,就是从起点开始,找到所有的满足起点到这个点的所有路径都不经过环的 点。

那么这个可以通过拓扑排序来实现。

qwq

只需要一开始先把所有的依赖关系,跑一遍拓扑排序。

然后选出来有效的点,再建图就ok

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
#define pb push_back
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 3010;
const int maxm = 2e6+1e2;
const int inf = 1e9;
int n,m,cnt=1;
int point[maxn],nxt[maxm],to[maxm],val[maxm];
int h[maxn],in[maxn];
int s,t;
int a[maxn][maxn];
int sum;
int num;
int dfn[maxn];
int tag[maxn];
vector<int> v[maxn];
void init()
{
cnt=1;
memset(point,0,sizeof(point));
memset(in,0,sizeof(in));
}
void add(int x,int y)
{
nxt[++cnt]=point[x];
to[cnt]=y;
point[x]=cnt;
in[y]++;
}
void addedge(int x,int y,int w)
{
nxt[++cnt]=point[x];
to[cnt]=y;
val[cnt]=w;
point[x]=cnt;
}
void insert(int x,int y,int w)
{
addedge(x,y,w);
addedge(y,x,0);
}
queue<int> q;
bool bfs(int s)
{
memset(h,-1,sizeof(h));
h[s]=0;
q.push(s);
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i=point[x];i;i=nxt[i])
{
int p=to[i];
if (h[p]==-1 && val[i]>0)
{
h[p]=h[x]+1;
q.push(p);
}
}
}
if (h[t]==-1) return false;
return true;
}
int dfs(int x,int low)
{
if (x==t || low==0) return low;
int totflow=0;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (h[p]==h[x]+1 && val[i]>0)
{
int tmp = dfs(p,min(low,val[i]));
val[i]-=tmp;
val[i^1]+=tmp;
low-=tmp;
totflow+=tmp;
if (low==0) return totflow;
}
}
if (low>0) h[x]=-1;
return totflow;
}
int dinic()
{
int ans=0;
while (bfs(s))
{
ans=ans+dfs(s,inf);
}
return ans;
}
int getnum(int x,int y)
{
return (x-1)*m+y;
}
void tpsort()
{
while (!q.empty()) q.pop();
for (int i=1;i<=num;i++)
{
if (!in[i]) q.push(i),tag[i]=1,dfn[i]=1;
}
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i=point[x];i;i=nxt[i])
{
int p=to[i];
in[p]--;
if (!in[p])
{
dfn[p]=dfn[x]+1;
q.push(p);
tag[p]=1;
}
}
}
}
int main()
{
n=read(),m=read();
num=n*m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
a[i][j]=read();
int num = read();
for (int k=1;k<=num;k++)
{
int x=read(),y=read();
x++,y++;
v[getnum(i,j)].pb(getnum(x,y));
add(getnum(i,j),getnum(x,y));
}
if (j!=m) add(getnum(i,j+1),getnum(i,j));
}
tpsort();
init();
s=maxn-10;
t=s+1;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
int now=getnum(i,j);
if(!tag[now]) continue;
if(a[i][j]>0) sum+=a[i][j];
for (int k=0;k<v[now].size();k++)
if (tag[v[now][k]]) insert(now,v[now][k],inf);
if (a[i][j]>0) insert(now,t,a[i][j]);
else insert(s,now,-a[i][j]);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
int now = getnum(i,j);
int ri = getnum(i,j+1);
if (j==m) continue;
if (!tag[now] || !tag[ri]) continue;
if (dfn[ri]>dfn[now]) swap(now,ri);
insert(ri,now,inf);
}
}
cout<<sum-dinic();
return 0;
}

洛谷2805 [NOI2009]植物大战僵尸 (拓扑排序+最小割)的更多相关文章

  1. P2805 [NOI2009]植物大战僵尸 (拓扑排序 + 最小割)

    题意:N*M的矩阵 每个点上都有一颗植物 僵尸只能从每一行的最右边向左进攻 每个植物有攻击范围 可以保护在攻击范围内的植物 同时每一颗植物也保护他左边的植物 摧毁每个植物能获得价值 如果这个植物被保护 ...

  2. 【BZOJ-1565】植物大战僵尸 拓扑排序 + 最小割

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1972  Solved: 917[Submit][Statu ...

  3. 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告

    P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...

  4. 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...

  5. 【bzoj1565】[NOI2009]植物大战僵尸 拓扑排序+最大权闭合图

    原文地址:http://www.cnblogs.com/GXZlegend/p/6808268.html 题目描述 输入 输出 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何 ...

  6. 2018.11.02 洛谷P2661 信息传递(拓扑排序+搜索)

    传送门 按照题意模拟就行了. 先拓扑排序去掉不在环上面的点. 剩下的都是简单环了. 于是都dfsdfsdfs一遍求出最短的环就行. 代码: #include<bits/stdc++.h> ...

  7. 洛谷P3243 [HNOI2015]菜肴制作 拓扑排序+贪心

    正解:拓扑排序 解题报告: 传送门! 首先看到它这个约束就应该要想到拓扑排序辣QwQ 首先想到的应该是用优先队列代替队列,按照节点编号排序 然后也很容易被hack:<5,1> 正解应为5, ...

  8. 【洛谷P4934】 礼物,拓扑排序

    题目大意:给你$n$个不重复的数,其值域为$[0,2^k)$,问你至少需要将这$n$个数拆成多少个集合,使得它们互相不是对方的子集,并输出方案. 数据范围:$n≤10^6$,$k≤20$. $MD$我 ...

  9. BZOJ 1565 植物大战僵尸(拓扑排序+最大权闭合子图)

    图中的保护关系就类似于最大权闭合子图.即你想杀x,你就一定要杀掉保护x的点,那么把x向保护它的点连边.那么题目就转化成了最大权闭合子图的问题. 但是这个图有点特殊啊... 考虑有环的情况,显然这个环以 ...

随机推荐

  1. JAVA 之 每日一记 之 算法( 给你一个Excel表列序号,返回出它对应的数字 )

    代码结果:(只想要代码的可以离开了,代码给你了,绝对能用的.想要思路的往下看.) class Solution { public int titleToNumber(String s) { int a ...

  2. Mybatis(二)——全局配置文件

    一.在正文上方直接添加目录. 1.二级标题***申请开通js权限 2.添加js脚本到页脚Html代码 数组:采用一段连续的存储单元来"存储"数据.对于"指定下标" ...

  3. Mysql - You can't specify target table '表名' for update in FROM clause 错误解决办法

    背景 在MySQL中,写SQL语句的时候 ,可能会遇到 You can't specify target table '表名' for update in FROM clause 这样的错误 错误含义 ...

  4. linux 档案权限篇之一

    一:预备知识 1.在linux中,任何一个档案都具有.所有者.用户组.其他用户这三种身份的个别权限. 1.所有者:即档案拥有者,由于Linux是多人多任务的系统,因此可能常常会有很多人同时使用这部主机 ...

  5. sass和js的联动(共享变量)

    一般做共享变量用于主题功能 假设我们在xxx.scss中声明了一个 theme:blue,我们在 js 中该怎么获取这个变量呢?我们可以通过import variables from '@/style ...

  6. python库--pandas--DataFrame

    转换    索引,迭代    运算符    功能应用,分组及窗口    计算/描述统计 重新索引/选择/标签操作    缺失数据处理    形状变换/排序/转置 组合/加入/合并    时间序列相关  ...

  7. RIAD配置

    一.RIAD 磁盘阵列介绍 二.阵列卡介绍 三.案例举例   一.RAID磁盘阵列介绍 是Redundant Array of Independent Disks的缩写,中文简称为独立冗余磁盘阵列 把 ...

  8. scrum项目冲刺_day11 第一阶段总结

    "智能垃圾分类APP"第一阶段总结 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已完成) 2.语音识别功能(已完成) 3.垃圾搜索功能(基本完成) 4 ...

  9. stderr,stdin,stdout相关

    转载请保留原作者. 目录 一.stdin和stdout 1.意义 2.缓冲 2.1.scanf的缓冲问题 2.2.fflush 3.freopen 二.stderr 1.输出方法 2.默认缓冲 一.s ...

  10. 学习PHP中好玩的Gmagick图像操作扩展的使用

    在 PHP 的图像处理领域,要说最出名的 GD 库为什么好,那就是因为它不需要额外安装的别的什么图像处理工具,而且是随 PHP 源码一起发布的,只需要在安装 PHP 的时候添加上编译参数就可以了. G ...