1565: [NOI2009]植物大战僵尸

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 2161  Solved: 1000
[Submit][Status][Discuss]

Description

Input

Output

仅包含一个整数,表示可以获得的最大能源收入。注意,你也可以选择不进行任何攻击,这样能源收入为0。

Sample Input

3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0

Sample Output

25

HINT

在样例中, 植物P1,1可以攻击位置(0,0), P2, 0可以攻击位置(2,1)。 
一个方案为,首先进攻P1,1, P0,1,此时可以攻击P0,0 。共得到能源收益为(-5)+20+10 = 25。注意, 位置(2,1)被植物P2,0保护,所以无法攻击第2行中的任何植物。 
【大致数据规模】
约20%的数据满足1 ≤ N, M ≤ 5;
约40%的数据满足1 ≤ N, M ≤ 10;
约100%的数据满足1 ≤ N ≤ 20,1 ≤ M ≤ 30,-10000 ≤ Score ≤ 10000 。

Source

 

[Submit][Status][Discuss]

HOME Back

————————————————我是分割线——————————————————————————

好题啊好题

这题折腾了三天,差点没吐出血来。

先拓扑排序求环,把环删掉。

之后重建图求最大权闭合子图,把一个植物向保护它的植物连边,跑一遍网络流即可。

第一次只过了4个点。不明所以。

换方法重写了拓扑,在网络流中加限制乱搞。

终于90,但第九个点一直RE,最后发现数组开小了。这题最多600个点,但边数组一直开到800005才A了。TAT~

 /*
Problem: bzoj 1565 [NOI2009]植物大战僵尸
OJ: bzoj
User: S.B.S.
Time: 264 MS
Memory: 13884 KB
Length: 6934 B
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iomanip>
#include<cassert>
#include<climits>
#include<functional>
#include<bitset>
#include<vector>
#include<list>
#define F(i,j,k) for(int i=j;i<=k;++i)
#define M(a,b) memset(a,b,sizeof(a))
#define FF(i,j,k) for(int i=j;i>=k;i--)
#define inf 0x3f3f3f3f
#define maxm 1001
#define mod 998244353
//#define LOCAL
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
int mp[];
struct EDGE
{
int from;
int to;
int value;
int next;
}e[];
int head[];
int v[],in[],out[];
int tot=;
inline void addedge(int u,int v,int w)
{
e[++tot].from=u;
e[tot].to=v;
e[tot].value=w;
e[tot].next=head[u];
head[u]=tot;
// tot++;
}
//bool kan[2000][2000];
int ans=;
//inline int at(int x,int y)
//{
// return m*x+y+1;
//}
//int stk[4001],top=0;
//inline void topsort()
//{
// int temp[4001];M(temp,0);
// F(i,1,m*n) temp[i]=in[i];
// F(i,1,m*n){
// if(in[i]==0){
// stk[top]=i;
//// cout<<i<<"********"<<endl;
// top++;
// }
// }
//// cout<<top<<": "<<endl;
//// F(i,0,top-1) cout<<stk[i]<<" ";cout<<endl;
// while(top!=0){
// top--;int u=stk[top];
// for(int i=head[u];i!=-1;i=e[i].next)
// {
// in[e[i].to]--;
// if(in[e[i].to]==0){
// stk[top]=e[i].to;
// top++;
// }
// }
// }
// F(i,1,m*n){
// if(in[i]!=0){
// stk[top]=i;
// top++;
// }
// }
// while(top!=0){
// top--;int u=stk[top];
// temp[u]=-1;out[u]=-1;
// v[u]=0;
// }
// F(i,1,m*n) in[i]=temp[i];
// return;
//}
inline void add(int u,int v,int w)
{
addedge(u,v,w);
addedge(v,u,);
++in[u];
return;
}
int map[];
int S,T;
bool ok()
{
F(i,S,T) if(map[i]!=-) map[i]=-;
int que[];
int hd=,tl=;
que[tl++]=S;
map[S]=;
while (hd<tl){
int u=que[hd++];
for(int i=head[u];i;i=e[i].next)
{
if(map[e[i].to]==-&&e[i].value)
{
map[e[i].to]=map[u]+;
que[tl++]=e[i].to;
}
}
}
// if (map[T]!=-1) return true;
// else return false;
return map[T]>;
}
int cur[];
int zeng(int k,int now)
{
if (k==T) return now;
int r=;
for (int i=cur[k];i&&now>r;i=e[i].next)
{
if (map[k]+==map[e[i].to]&&e[i].value)
{
int t=zeng(e[i].to,min(now-r,e[i].value));
e[i].value-=t;e[i^].value+=t;r+=t;
if(e[i].value) cur[k]=i;//***
// cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<t<<endl;
}
}
if (!r) map[k]=-;
return r;
}
int dinic()
{
int r=,t;
M(cur,);
while (ok()){
for(int i=S;i<=T;++i) cur[i]=head[i];
r+=zeng(S,inf);
// while(t=zeng(S,inf)) r+=t;
}
return r;
}
//pair<int,int> kk[4001];
//int cur;
int main()
{
std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
#ifdef LOCAL
freopen("111.in","r",stdin);
freopen("data.out","w",stdout);
#endif
cin>>n>>m;
S=;T=m*n+;
M(mp,);M(head,);
// F(i,0,n-1)F(j,0,m-1){
// int x,y;
// cin>>x>>y;
// mp[i][j]=x;
// v[at(i,j)]=x;
// in[at(i,j)]++;
// if(j==m-1) in[at(i,j)]--;
// if(j!=0) add(at(i,j),at(i,j-1),v[at(i-1,j)]);
// if(y==0) continue;
//// **********************************************
// F(k,1,y){
// int a,b;
// cin>>a>>b;
// kk[cur].first=at(i,j);
// kk[cur].second=at(a,b);
// cur++;
// in[at(a,b)]++;
// addedge(at(i,j),at(a,b),0);
//// cout<<at(i,j)<<" "<<at(a,b)<<" &&&&&"<<endl;
// }
// }
// F(i,1,m*n) cout<<in[i]<<" ";cout<<endl;
// cout<<"/*****************************"<<endl;
// F(i,1,tot) cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<e[i].value<<endl;
// cout<<"*****************************/"<<endl;
F(i,,n*m){
int temp;
cin>>mp[i];
if(mp[i]>) add(S,i,mp[i]);
else add(i,T,-mp[i]);
cin>>temp;
while(temp--){
int x,y;
cin>>x>>y;
add(x*m+y+,i,inf);
}
if(i%m) add(i,i+,inf);
}
// topsort();
// cout<<"))))))"<<endl;
// F(i,1,m*n) if(in[i]==-1) cout<<i<<" ";cout<<"((((("<<endl;
// M(e,0);M(head,-1);tot=0;
int q[];M(q,);
int cur1=,cur2=;
for(int i=S;i<=T;++i){
if(!in[i]) q[cur2++]=i;
map[i]=-;
}
int sum=;
while(cur1<cur2){
int cnt=q[cur1++];map[cnt]=;
if(mp[cnt]>) sum+=mp[cnt];
for(int i=head[cnt];i;i=e[i].next)
{
if(i&) if(!--in[e[i].to]) q[cur2++]=e[i].to;
}
}
// F(i,1,m*n) cout<<in[i]<<" ";cout<<endl;
// cout<<"v: "<<endl;
// F(i,1,m*n) cout<<v[i]<<" ";cout<<endl;
// F(i,0,n-1)F(j,0,m-1){
// if(in[at(i,j)]==-1) continue;
//// cout<<at(i,j)<<" : "<<in[at(i,j)]<<"@ "<<endl;
// if(j!=0&&in[at(i,j-1)]!=-1) add(at(i,j-1),at(i,j),inf);
// if(v[at(i,j)]==0) continue;
// if(v[at(i,j)]>0) add(31,at(i,j),v[at(i,j)]),sum+=v[at(i,j)];
// else add(at(i,j),32,-v[at(i,j)]);
// }
// while(cur!=0){
// cur--;
// if(in[kk[cur].first]==-1||in[kk[cur].second]==-1) continue;
// int u=kk[cur].first;
// int v=kk[cur].second;
// add(v,u,inf);
// }
// cout<<"/*****************************"<<endl;
// F(i,1,tot) cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<e[i].value<<endl;
// cout<<"*****************************/"<<endl;
// cout<<sum<<endl;
cout<<sum-dinic()<<endl;
return ;
}
/*
3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
*/

植物大战僵尸

bzoj 1565 [NOI2009]植物大战僵尸 解题报告的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ 1565 NOI2009 植物大战僵尸 topo+最小割(最大权闭合子图)

    题目链接:https://www.luogu.org/problemnew/show/P2805(bzoj那个实在是有点小小的辣眼睛...我就把洛谷的丢出来吧...) 题意概述:给出一张有向图,这张有 ...

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

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

  7. bzoj 1565 [NOI2009]植物大战僵尸【tarjan+最大权闭合子图】

    一上来以为是裸的最大权闭合子图,上来就dinic -然后没过样例.不得不说样例还是非常良心的给了一个强连通分量,要不然就WA的生活不能自理了 然后注意到有一种特殊情况:每个植物向他保护的植物连边(包括 ...

  8. 1565: [NOI2009]植物大战僵尸 - BZOJ

    Description Input Output仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0.Sample Input3 210 020 0-10 0 ...

  9. BZOJ 1565: [NOI2009]植物大战僵尸

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

随机推荐

  1. 关于linux时间

    时区确定cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 查看硬件时间hwclock --show 将系统时间写入硬件时间hwclock --sy ...

  2. 四、django rest_framework源码之频率控制剖析

    1 绪言 权限判定之后的下一个环节是访问频率控制,本篇我们分析访问频率控制部分源码. 2 源码分析 访问频率控制在dispatch方法中的initial方法调用check_throttles方法开始. ...

  3. 试水jdk8 stream

    jdk8出来日子不短了,jdk11都出来了,不过用的最多的不过是1.5罢了. 今年终于鼓起勇气认真对待它,在18年记录下学习stream,画上一个圆. 先看个图 Java8中有两大最为重要的改变.第一 ...

  4. 今日头条高级后端开发实习生三轮技术面+HR面 面经

    二面结束后已经意识模糊,好多问过的东西都忘了,而且有一些基础知识就不在这写了,大部分公司都问的差不多... 一面(2018/03/27,11:00~11:50) 1:自我介绍 2:简单说说你这个项目吧 ...

  5. 第2天:Django路由与视图

    在应用中创建视图定义路由 配置文件说明 静态文件使用 Django解析路由的流程 路由顺序 路由命名与reverse反推 在应用中创建视图定义路由 前面我们已经创建了子应用users,但是这个user ...

  6. hdu 2216 bfs

    题目大意:两个东西朝相同方向移动Sample Input4 4XXXX.Z...XS.XXXX4 4XXXX.Z...X.SXXXX4 4XXXX.ZX..XS.XXXXSample Output11 ...

  7. ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力

    C. Om Nom and Candies Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/526 ...

  8. Running CMD.EXE as Local System(转)

    Many times in the past I had to run an interactive command-line shell under the Local SYSTEM account ...

  9. Android Path Time ScrollBar(Path 时间轴)

    版本号:1.0 日期:2014.4.22 版权:© 2014 kince 转载注明出处   这是仿Path2.0UI的一个demo的截图,我最早是在农民伯伯的这篇博客中看到的[Andorid X 项目 ...

  10. 探究Linux下参数传递及查看和修改方法

    http://m.blog.csdn.net/blog/moonvs2010/11392959