洛谷$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连边 ...
随机推荐
- @loj - 2434@ 「ZJOI2018」历史
目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的 ...
- LeetCode54 Spiral Matrix
题目: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spira ...
- shell爬虫
#!/bin/bash curl_str='curl -x "http://http-pro.abuyun.com:9010" --proxy-basic --proxy-user ...
- 1 项目里面如何打印log日志
1 首先写一个logging.py文件 import logging from conf import setting #配置文件,里面有日志存放路径 def mylog(): logger = l ...
- 洛谷P2330 [SCOI2005]繁忙的都市
#include<bits/stdc++.h> using namespace std; ; ; int n,k,Max,tot; struct node{ int cnt,fa; }f[ ...
- @bzoj - 2388@ 旅行规划
目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你维护一个序列,支持两种操作: (1)某个区间 [x, y] ...
- PHP 网站大流量与高并发的解决方法
php 网站如何应对大流量与高并发呢? 首先,确认服务器硬件是否足够支持当前的流量. 普通的P4服务器一般最多能支持每天10万地理IP,如果访问量比这个还要大,则请配置一台更高性能的专用服务器. 否则 ...
- Project Euler Problem 21-Amicable numbers
先说最暴力的算法,直接对一万内的每个数字暴力分解因子(对每个数字的时间复杂度是O(sqrt(n)的),然后,用个数组记录下来因子和,然后寻找 亲密数. 好一点:要先打个素数表,然后对每个数字,分解素因 ...
- 【CSS3 + 原生JS】移动的标签
左图为本博客右侧截取的GIF图,右图为代码效果 HTML: <!DOCTYPE html> <html lang="en"> <head> &l ...
- 在Element节点上进行Xpath
XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xpath = xPathFactory.newXPath(); try { ...