这题应该分两步来做:

1、拓扑排序,去掉无敌点

2、求最大闭合子图

需要注意几点:

1、拓扑排序时,如果(i,j)可以攻击到(x,y),那么增加(x,y)的入度,而不是(i,j)的入度

因为入度代表着要攻击它需要事先攻击几个点

2、求最大闭合子图时,用所有的正权点-最大流

3、求最大闭合子图时,如果(i,j)可以攻击到(x,y),那么连一条边(x,y)到(i,j),容量为正无穷

因为在最大闭合子图中边(x,y)到(i,j)意味着选(x,y)就必须要选(i,j),这与实际含义相符

4、s到正权点,容量为正权点的点权

负权点到t,容量为负权点的点权的绝对值

5、要做好对数据规模的估计

代码:

 type node=record
go,next,c:longint;
end;
var e:array[..] of node;
head,tail,i,n,m,j,tot,max,ans,s,t,x,y:longint;
w,cur,first,inp,q,h:array[..] of longint;
can:array[..] of boolean;
a:array[..,..] of longint;
procedure insert(x,y,z:longint);
begin
inc(tot);
e[tot].go:=y;
e[tot].c:=z;
e[tot].next:=first[x];
first[x]:=tot;
inc(tot);
e[tot].go:=x;
e[tot].c:=;
e[tot].next:=first[y];
first[y]:=tot;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure init;
begin
readln(n,m);
fillchar(inp,sizeof(inp),);
for i:= to n*m do
begin
read(w[i]);read(a[i,]);
for j:= to a[i,] do
begin
read(x,y);inc(x);inc(y);
a[i,j]:=(x-)*m+y;
inc(inp[(x-)*m+y]);
end;
if i mod m<> then
begin
inc(a[i,]);a[i,a[i,]]:=i-;inc(inp[i-]);
end;
readln;
end;
end;
procedure topsort;
begin
head:=;tail:=;
fillchar(q,sizeof(q),);
fillchar(can,sizeof(can),false);
for i:= to n*m do
if inp[i]= then
begin
can[i]:=true;inc(tail);q[tail]:=i;
end;
while head<tail do
begin
inc(head);
x:=q[head];
for i:= to a[x,] do
begin
y:=a[x,i];
dec(inp[y]);
if inp[y]= then
begin
can[y]:=true;
inc(tail);
q[tail]:=y;
end;
end;
end;
end;
procedure makegraph;
begin
max:=;
for i:= to n*m do
if can[i] then
begin
if w[i]> then inc(max,w[i]);
for j:= to a[i,] do
begin
y:=a[i,j];
if can[y] then insert(y,i,maxlongint>>);
end;
if w[i]> then insert(s,i,w[i])
else insert(i,t,-w[i]);
end;
end;
function bfs:boolean;
var i,x,y:longint;
begin
fillchar(h,sizeof(h),);
fillchar(q,sizeof(q),);
head:=;tail:=;q[]:=s;h[s]:=;
while head<tail do
begin
inc(head);
x:=q[head];
i:=first[x];
while i<> do
begin
y:=e[i].go;
if (h[y]=) and (e[i].c<>) then
begin
h[y]:=h[x]+;
inc(tail);
q[tail]:=y;
end;
i:=e[i].next;
end;
end;
exit(h[t]<>);
end;
function dfs(x,f:longint):longint;
var i,y,tmp,used:longint;
begin
if (x=t) or (f=) then exit(f);
i:=cur[x];tmp:=;used:=;
while i<> do
begin
y:=e[i].go;
if (h[y]=h[x]+) and (e[i].c<>) then
begin
tmp:=dfs(y,min(e[i].c,f-used));
dec(e[i].c,tmp);
inc(e[i xor ].c,tmp);
if e[i].c<> then cur[x]:=i;
inc(used,tmp);
if used=f then exit(f);
end;
i:=e[i].next;
end;
if used= then h[x]:=-;
exit(used);
end; procedure dinic;
begin
while bfs do
begin
for i:= to n*m+ do cur[i]:=first[i];
inc(ans,dfs(s,maxlongint>>));
end;
end; procedure main;
begin
tot:=;
s:=;t:=n*m+;
topsort;
makegraph;
dinic;
writeln(max-ans);
end;
begin
init;
main;
end.

NOI2009植物大战僵尸的更多相关文章

  1. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  2. P2805 [NOI2009]植物大战僵尸

    题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...

  3. COGS410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

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

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

  5. 【刷题】BZOJ 1565 [NOI2009]植物大战僵尸

    Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻. ...

  6. 【bzoj1565】[NOI2009]植物大战僵尸

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

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

    dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...

  8. BZOJ1565: [NOI2009]植物大战僵尸

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

  9. 【bzoj1565】 NOI2009—植物大战僵尸

    http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接) 题意 给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保 ...

  10. luogu2805 [NOI2009]植物大战僵尸

    想象一下,要搞掉一个植物,必须先搞掉另一些植物--我们可以发现这是一个最大权闭合子图的问题. 最大权闭合子图的话,太空飞行计划问题是一个入门题,可以一看. 然而我们手玩一下样例就会惊恐地发现,保护关系 ...

随机推荐

  1. Python 信号量

    信号的概念 信号(signal)--     进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号. 几个常用信号: SIGINT     终止进程  中断进 ...

  2. EXTJS 4.2 资料 控件之Window窗体自动填充页面

    1.html页面代码: <div id="component" style="width:100%;height:100%"> <body&g ...

  3. setTimeOut传参数(转)

    无论是window.setTimeout还是window.setInterval,在使用函数名作为调用句柄时都不能带参数.带参数则立马执行,没有延时效果.可通过下面方式实现.  <script  ...

  4. hdu 4712 Hamming Distance(随机函数暴力)

    http://acm.hdu.edu.cn/showproblem.php?pid=4712 Hamming Distance Time Limit: 6000/3000 MS (Java/Other ...

  5. 2734: [HNOI2012]集合选数 - BZOJ

    Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中 ...

  6. 解决eclipse“copy项目重命名后重新发布,项目名在地址栏仍然是原来的项目名”的问题

    任务描述:复制项目spring_user并重命名为spring_user_test 一.通过按F2和以下方式可以修改目标项目在workspace的名字 点击项目右键选择properties,输入关键字 ...

  7. 在TNSNAMES.ORA文件中配置本机装的oracle

    首先,感谢这两位网友:http://zhidao.baidu.com/link?url=eGYeoEa-EhQdVitSGqjE36uNfVmEsryXH1WUjPue6YvArDSx-Y1N9_rd ...

  8. WPF SplitButton 的杂七杂八

    原文: http://www.codeproject.com/Articles/20612/A-WPF-SplitButton SplitButton.cs using System; using S ...

  9. 【C++基础】 多态 虚函数

    多态:同样的消息被不同类型的对象接收时导致不同的行为.这里“消息”是对类的成员函数的调用,“行为”调用了不同的函数. 分类:①重载多态 ②包含多态……等 实现:编译时的多态  运行时的多态(动态绑定) ...

  10. [扫描线]POJ2932 Coneology

    题意:有n个圆 依次给了半径和圆心坐标  保证输入的圆不相交(只有 相离 和 内含/外含 的情况)   问 有几个圆 不内含在其他圆中,并分别列出这几个圆的编号(1~n) (n的范围是[1, 4000 ...