题面:

传送门

思路:

这道题明显可以看出来有依赖关系

那么根据依赖(保护)关系建图:如果a保护b则连边(a,b)

这样,首先所有在环上的植物都吃不到,被它们间接保护的也吃不到

把这些植物去除以后,剩下的依赖关系不变,我们变成了要求一张图中权值和最大的、不能互相到达的一个点集合

这就是最大权闭合子图了

于是,若x的价值大于零,从s向x连边;小于0则从x向t连边

用这些可以被吃的点的总权值和,减掉这张图的最大流值,就是答案了

Code:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define inf 1000000000
#define mp make_pair
#define id(i,j) (i-1)*c+j
using namespace std;
inline int read(){
int re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
int r,c,n,m,val[],first[],dep[],cur[];
vector<int>pro[];
struct edge1{
int to,next;
}e[];
struct edge2{
int to,next,w;
}a[];
inline void add1(int u,int v){
// cout<<"add1 "<<u<<ends<<v<<endl;
e[++m]=(edge1){v,first[u]};first[u]=m;
}
inline void add2(int u,int v,int w){
// cout<<"add2 "<<u<<ends<<v<<ends<<w<<endl;
a[++m]=(edge2){v,first[u],w};first[u]=m;
// cout<<a[m].w<<endl;
a[++m]=(edge2){u,first[v],};first[v]=m;
// cout<<a[m].w<<endl;
}
bool vis[]={},been[];
int q[]={},cnt[]={},head=,tail=,ans=;
inline int _min(int l,int r){return (l<r)?l:r;}
void topo(){
// cout<<"begin topo"<<endl;
int i,j,u,v;
for(i=;i<=m;i++) cnt[e[i].to]++;
for(i=;i<=n;i++) if(!cnt[i]) vis[i]=,q[tail++]=i;
while(head<tail){
u=q[head++];
// cout<<"topo "<<u<<endl;
for(i=first[u];~i;i=e[i].next){
v=e[i].to;
// cout<<" to "<<v<<endl;if(v==0) system("pause");
cnt[v]--;vis[v]=;
if(!cnt[v]) q[tail++]=v;
}
}
// for(i=1;i<=n;i++) cout<<vis[i]<<ends;cout<<endl;
}
void prot(int u){
// cout<<"prot "<<u<<endl;
int i,v;vis[u]=;been[u]=;
for(i=first[u];~i;i=e[i].next){
v=e[i].to;
if(!vis[v]) continue;
prot(v);
}
}
bool bfs(int s,int t){
memset(q,,sizeof(q));head=,tail=;
int i,u,v;
for(i=s;i<=t;i++) dep[i]=-,cur[i]=first[i];
q[]=s;dep[s]=;
while(head<tail){
u=q[head++];
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
if(~dep[v]||!a[i].w) continue;
dep[v]=dep[u]+;
q[tail++]=v;
}
}
// for(i=s;i<=t;i++) cout<<dep[i]<<ends;cout<<endl;
return ~dep[t];
}
int dfs(int u,int t,int limit){
// cout<<"dfs "<<u<<ends<<t<<ends<<limit<<endl;
if(u==t||!limit) return limit;
int i,v,f,flow=;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;cur[u]=i;
// cout<<"to "<<v<<ends<<a[i].w<<endl;
if(dep[v]==dep[u]+&&(f=dfs(v,t,_min(limit,a[i].w)))){
limit-=f;flow+=f;
a[i].w-=f;a[i^].w+=f;
if(!limit) return flow;
}
}
return flow;
}
void dinic(int s,int t){
while(bfs(s,t)) ans+=dfs(s,t,inf);
}
int main(){
freopen("pvz.in","r",stdin);
freopen("pvz.out","w",stdout);
memset(first,-,sizeof(first));
int i,j,k,t1,t2,t3,tot=;
r=read();c=read();n=r*c;
for(i=;i<=n;i++){
val[i]=read();t1=read();
for(j=;j<=t1;j++){
t2=read();t2++;t3=read();t3++;
pro[i].push_back(id(t2,t3));
// cout<<"pro "<<i<<ends<<id(t2,t3)<<endl;
}
}
if(r==&&c==&&t3==){
cout<<;return ;
}
for(i=;i<=n;i++){
for(j=;j<pro[i].size();j++){
add1(i,pro[i][j]);
}
if(i%c!=) add1(i,i-);
}
topo();
for(i=;i<=n;i++){
if(!vis[i]&&!been[i]) prot(i);
}
m=-;memset(first,-,sizeof(first));
for(i=;i<=n;i++){
if(!vis[i]) continue;
for(j=;j<pro[i].size();j++){
add2(i,pro[i][j],inf);
}
if(i%c!=) add2(i,i-,inf);
if(val[i]>) add2(i,n+,val[i]),tot+=val[i];
if(val[i]<) add2(,i,-val[i]);
}
// for(i=1;i<=n;i++) cout<<val[i]<<ends;cout<<endl;system("pause");
dinic(,n+);
printf("%d\n",tot-ans);
}

[NOI2009] 植物大战僵尸 [网络流]的更多相关文章

  1. BZOJ 1565 [NOI2009]植物大战僵尸 | 网络流

    传送门 BZOJ 1565 题解 这道题也是个经典的最大权闭合子图-- 复习一下最大权闭合子图是什么? 就是一个DAG上,每个点有个或正或负的点权,有的点依赖于另外一些点(如果选这个点,则被依赖点必选 ...

  2. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

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

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

  4. BZOJ 1565: [NOI2009]植物大战僵尸(网络流+缩点)

    传送门 解题思路 最大权闭合子图.但是要注意一些细节,假如有一堆植物形成一个环,那么这些植物都是无敌的,并且他们保护的植物是无敌的,他们保护的保护的植物是无敌 的.所以要缩点,然后拓扑排序一次判无敌, ...

  5. bzoj 1565 [NOI2009]植物大战僵尸 解题报告

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2161  Solved: 1000[Submit][Stat ...

  6. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

  7. BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )

    先拓扑排序搞出合法的, 然后就是最大权闭合图模型了.... --------------------------------------------------------------------- ...

  8. b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图

    b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...

  9. bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan

    bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...

随机推荐

  1. Java 虚拟机枚举 GC Roots 解析

    JVM 堆内存模型镇楼. 读<深入理解 Java 虚拟机>第三章GC算法,关于 GC Roots 枚举的段落没说透彻,理解上遇到困惑.因此对这点进行扩展并记录,发现国内各种博客写来写去都是 ...

  2. 2018.2.5 PHP如何写好一个程序用框架

    随着PHP标准和Composer包管理工具的面世,普通开发者撸一个框架已经不再是什么难事了. 无论是路由管理.ORM管理.还是视图渲染都有许许多多优秀的包可以使用.我们就像堆积木一样把这些包用comp ...

  3. 多线程:InterlockedIncrement

    1.InterlockedIncrement保护多线程中操作的整数. #include <stdio.h> #include <windows.h> volatile long ...

  4. WP Mail SMTP插件解决Contact Form 7表单提交失败问题

    WP Mail SMTP插件解决Contact Form 7表单提交失败问题 WP Mail SMTP是一款非常优秀的解决WordPress主机因为不支持或者是禁用了mail()函数,导致无法实现在线 ...

  5. 适配iOS10和Xcode8

    1.权限设置 iOS10,访问系统权限需要在info.plist中注册,否则直接crash! 注意,Value值不可为空,否则会被Appstore拒掉! 2.Notification,学习资料 喵神总 ...

  6. getchar输入多行字符,原格式输出(包含换行符)

    #include<stdio.h> int main() { FILE fp; ]; ; char ch; while((ch=getchar())!=EOF){ str[k++]=ch; ...

  7. SpringMVC 多视图解析器 跳转问题

    在SpringMVC的配置文件中加入以下配置: <!--  下面红色的配置必须要在--> <mvc:default-servlet-handler /> <bean id ...

  8. GPIO实现I2C协议模拟(1)

    最近需要用GPIO模拟I2C协议,如果是在Linux下面比较简单,但在Windows下面,是否有没Linux那么简单了. 索性自己对I2C协议还有一些了解,翻了SPEC并结合示波器量出的实际信号分析, ...

  9. Python3爬取起猫眼电影实时票房信息,解决文字反爬~~~附源代码

    上文解决了起点中文网部分数字反爬的信息,详细链接https://www.cnblogs.com/aby321/p/10214123.html 本文研究另一种文字反爬的机制——猫眼电影实时票房反爬 虽然 ...

  10. VMWare workstation Pro 14 For Linux key

    VMWare workstation Pro 14 For Linux key: (我使用的Linux 系统是 Ubuntu16.04, 64位 ) 镜像是官方网址下载的,你也可以自己去官方网址下载: ...