洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流
正解:网络流
解题报告:
题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价($S$可正可负.另外每株植物有$A_{(x,y)}$个可攻击位置,只要这株植物不死这些位置都是无法到达的$QwQ$.攻击规则是必须从右向左走,如果要攻击$(x,y)$位置的植物,需要把第$x$行在$y$右侧的所有植物都击溃才行$QwQ$
$umm$然后先考虑要击溃一株植物的前提$QwQ$?就说要击溃这株植物的话首先一定要击溃它右侧的那株植物和保护它的植物.那就是个最大权闭合子图问题?所以考虑最小割?
于是给$S_{(x,y)}$为正的点建一排点,为负的建一排点.分别和$S$,$T$连流量为$S_{x,y}$的绝对值的边.然后考虑边之间怎么连?发现就每个点向它右侧的那个点和保护它的点连个流量为$inf$的边就成$QwQ$
然后发现还有点儿问题?就说如果有互相保护的点就不能攻击,同时这两点保护的点也都不能攻击,可以先预处理把这些点直接不考虑$QwQ$.拓扑排序或者$tarjan$都成?因为我$tarjan$学得布星所以大概会用拓扑,$QwQ$
$over$
然后槽下自己码力,,,就明明实现不难,然后硬是打了几个小时,,,改了好久,,,
所以说,这里的拓扑排序建图要注意下,一定要想清楚了再打,我开始没想清楚就瞎打,发现$WA$了之后就再改,拆东墙补西墙的反而影响了思路,,,最后是重新理了遍思路重新打了遍才$AC$的,,,$QwQ$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define n(i) edge[i].nxt
#define ri register int
#define rb register int
#define rc register char
#define t_tmp(i) edge_tmp[i].to
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define e(i,x) for(ri i=head[x];~i;i=n(i))
#define e_tmp(i,x) for(ri i=head_tmp[x];i;i=edge_tmp[i].nxt) const int N=,M=,inf=1e9;
int n,m,dep[N],head[N],cur[N],S,T,in[N],nam[M][M],nam_cnt,ed_cnt=-,ed_tmp_cnt,head_tmp[N],s[N],sum;
bool vis[N];
vector<int>V[N];
struct ed{int to,nxt,wei;}edge[N<<];
struct ed_tmp{int to,nxt;}edge_tmp[N*]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void ad(ri x,ri y,ri z)
{
//printf("%d -> %d : %d\n",y,x,z);
edge[++ed_cnt]=(ed){x,head[y],z};head[y]=ed_cnt;edge[++ed_cnt]=(ed){y,head[x],};head[x]=ed_cnt;
}
il void ad_tmp(ri x,ri y)
{edge_tmp[++ed_tmp_cnt]=(ed_tmp){x,head_tmp[y]};head_tmp[y]=ed_tmp_cnt;++in[x];}
il bool bfs()
{
queue<int>Q;Q.push(S);memset(dep,,sizeof(dep));dep[S]=;
while(!Q.empty()){ri nw=Q.front();Q.pop();/*printf("dep[%d]=%d\n",nw,dep[nw]);*/e(i,nw)if(w(i) && !dep[t(i)])dep[t(i)]=dep[nw]+,Q.push(t(i));}
return dep[T];
}
il int dfs(ri nw,ri flow)
{
//printf("nw=%d flow=%d\n",nw,flow);
if(nw==T || !flow)return flow;ri ret=;
for(ri &i=cur[nw];~i;i=n(i))
if(w(i) && dep[t(i)]==dep[nw]+){ri d=dfs(t(i),min(flow,w(i)));w(i)-=d,flow-=d,ret+=d,w(i^)+=d;}
return ret;
}
il int dinic(){ri ret=;while(bfs()){/*printf("QwQ? dep[T]=%d\n",dep[T]);*/rp(i,S,T)cur[i]=head[i];while(int d=dfs(S,inf))ret+=d;}return ret;}
il void tpst()
{
queue<int>Q;rp(i,S+,T-)if(!in[i])Q.push(i);
while(!Q.empty())
{
ri nw=Q.front();vis[nw]=;Q.pop();
e_tmp(i,nw)
{
--in[t_tmp(i)];
if(!in[t_tmp(i)])Q.push(t_tmp(i));
}
}
} int main()
{
//freopen("2805.in","r",stdin);freopen("2805.out","w",stdout);
n=read();m=read();rp(i,,n)rp(j,,m)nam[i][j]=++nam_cnt;S=;T=++nam_cnt;memset(head,-,sizeof(head));
rp(i,,n)
{
rp(j,,m)
{
if(j!=m)ad_tmp(nam[i][j],nam[i][j+]),V[nam[i][j]].push_back(nam[i][j+]);
s[nam[i][j]]=read();ri tmp=read();
rp(k,,tmp){ri x=read()+,y=read()+;ad_tmp(nam[x][y],nam[i][j]);V[nam[x][y]].push_back(nam[i][j]);}
}
}
tpst();
rp(i,S+,T-)
{
if(!vis[i])continue;
if(s[i]>)ad(i,S,s[i]),sum+=s[i];else ad(T,i,-s[i]);
ri sz=V[i].size();
rp(j,,sz-)if(vis[V[i][j]])ad(V[i][j],i,inf);
}
printf("%d\n",sum-dinic());
return ;
}
洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流的更多相关文章
- 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告
P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...
- BZOJ 1565 Luogu P2805 [NOI2009]植物大战僵尸 (Tarjan判环、最小割)
我: "立个flag 14点之前调完这题" 洛谷AC时间: 2019-06-24 14:00:16 实力打脸... 网络流板子从来写不对系列 题目链接: (BZOJ) https: ...
- BZOJ 1565 [NOI2009]植物大战僵尸 | 网络流
传送门 BZOJ 1565 题解 这道题也是个经典的最大权闭合子图-- 复习一下最大权闭合子图是什么? 就是一个DAG上,每个点有个或正或负的点权,有的点依赖于另外一些点(如果选这个点,则被依赖点必选 ...
- [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]
Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...
- P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序
传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...
- 【BZOJ1565】【NOI2009】植物大战僵尸 网络流 最大权闭合子图
题目大意 给你一个\(n\times m\)的地图,每个格子上都有一颗植物,有的植物能保护其他植物.僵尸从右往左进攻,每吃掉一颗植物就可以得到\(a_{i,j}\)的收益(\(a_{i,j}\)可 ...
- P2805 [NOI2009]植物大战僵尸(最小割+拓扑排序)
题意: n*m的矩阵,每个位置都有一个植物.每个植物都有一个价值(可以为负),以及一些它可以攻击的位置.从每行的最右面开始放置僵尸,僵尸从右往左行动,当僵尸在植物攻击范围内时会立刻死亡.僵尸每到一个位 ...
- [NOI2009] 植物大战僵尸 [网络流]
题面: 传送门 思路: 这道题明显可以看出来有依赖关系 那么根据依赖(保护)关系建图:如果a保护b则连边(a,b) 这样,首先所有在环上的植物都吃不到,被它们间接保护的也吃不到 把这些植物去除以后,剩 ...
- BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)
题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...
随机推荐
- oracle访问Table的方式
ORACLE 采用两种访问表中记录的方式: a. 全表扫描 全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描. b ...
- Getting started with the basics of programming exercises_2
1.编写简单power函数 #include<stdio.h> int power(int m, int n); // test power function int main(void) ...
- 如何把thinkphp 的url改为.html
ThinkPHP支持伪静态URL设置,可以通过设置URL_HTML_SUFFIX参数随意在URL的最后增加你想要的静态后缀,而不会影响当前操作的正常执行.例如,我们设置'URL_HTML_SUFFIX ...
- hdu 5745 La Vie en rose(2016多校第二场)
La Vie en rose Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- P3899 [湖南集训]谈笑风生 主席树
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...
- 获取checkbox返回值
<div class="checkbox"> <label> <input type="checkbox" value=" ...
- HTML静态网页--JavaScript-Window.document对象
1.Window.document对象 一.找到元素: docunment.getElementById("id"):根据id找,最多找一个: var a =docunmen ...
- JavaScript 数组去重和对象相等判断
前几天电话面试问到了数组去重和两个对象相等判断,当时回答的不是特别好,都过去好几天了,总结下. 1.数组去重 当时的问题是这样的有个简单的数组[1,1,2,3],去重后的结果是[1,2,3],怎么实现 ...
- excel求和结果不对
excel求和结果不对 Excel求和功能是excel中最常用的功能,但是很多时候会碰到各种错误,比如求和结果总是0.公式求和结果和用计算器敲出来的结果不一样.更新了数据但是求和结果没有变等等.本经验 ...
- nginx+tomcat实现负载均衡(windows环境)
一.准备工作 nginx1.14 nginx1.14下载链接 tomcat8 tomcat8下载链接 windows系统 二.实现目标 访问http://localhost地址时, 将请求轮询到tom ...