题目链接:https://www.luogu.org/problemnew/show/P2805(bzoj那个实在是有点小小的辣眼睛。。。我就把洛谷的丢出来吧。。。)

题意概述:给出一张有向图,这张有向图上的每个点都有一个点权,想要访问某个点必须要先访问这个点所能够访问(遍历)到的所有点,在访问到一个点之后将会得到这个点的权值(可正可负)。问访问这张图可以得到的最大点权和。

原题说过来说过去实际上是描述了一个植物之间的保护关系,也就是说明了植物之间的先后访问顺序之间的关系。可以描述为要“要访问点a,先要访问点b”这样的形式,并且题意总结出来之后很容易发现这就是一个最大权闭合子图问题。

但是我们注意到原题给出的并不一定是一个DAG图。事实上,可能有些植物互相保护,导致僵尸只能当炮灰。。。。于是我们需要把环去掉,这一步可以topo序解决,只是不是真的topo,而是从入度为0的点开始的(访问所有可以不经过环就可以访问到的点)。

然后就是直接网络流上跑最大权闭合子图。但是值得注意的是最大权闭合子图是满足一种推导关系,即上面的“要访问点a,先要访问先b”这种关系形成的一条有向边,容量为inf,因为要满足这样的推导关系,所以上面求topo的时候连的边要反过来。然后原点向所有点权为正的边连一条边,容量为点权;所有点权为负的点向汇点连一条边,容量为点权的相反数。在求最小割的时候如果一条边被割掉,那么意义就是做出选择(S有关的边是不选这个点,T有关的边是选了这个点)之后付出的代价。

最后只需要把所有的正权点权值相加(可以得到的最大收益),减去最小割(付出的最小代价),就是我们最终获得的最大收益。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int MAXN=;
const int MAXM=; int N,M,sco[MAXN][MAXM];
struct XY{ int x,y; };
vector<XY>att[MAXN][MAXM];
struct graph{
static const int maxn=;
static const int maxm=;
struct edge{ int from,to,next; }E[maxm];
int n,first[maxn],np,rd[maxn],topo[maxn];
graph(){ np=; }
void add_edge(int u,int v){
E[++np]=(edge){u,v,first[u]};
first[u]=np;
}
void topo_sort(){
queue<int>q;
for(int i=;i<=n;i++)
if(!rd[i]) topo[i]=,q.push(i);
while(!q.empty()){
int i=q.front(); q.pop();
for(int p=first[i];p;p=E[p].next){
int j=E[p].to;
if(--rd[j]==) topo[j]=,q.push(j);
}
}
}
}gp;
struct NET{
static const int maxn=;
static const int maxm=;
static const int inf=1e7+;
struct edge{ int from,to,next,cap,flow; }E[maxm<<];
int S,T,n,first[maxn],np,fl[maxn],gap[maxn],d[maxn],cur[maxn];
NET(){ np=; }
void add_edge(int u,int v,int w){
E[++np]=(edge){u,v,first[u],w,};
first[u]=np;
E[++np]=(edge){v,u,first[v],,};
first[v]=np;
}
void BFS(){
queue<int>q;
for(int i=;i<=n;i++) d[i]=n;
d[T]=; q.push(T);
while(!q.empty()){
int i=q.front(); q.pop();
for(int p=first[i];p;p=E[p].next){
int j=E[p].to,pp=(p-^)+;
if(E[pp].cap>E[pp].flow&&d[j]==n) d[j]=d[i]+,q.push(j);
}
}
}
int augment(){
int now=T,flow=inf;
while(now!=S){
flow=min(flow,E[fl[now]].cap-E[fl[now]].flow);
now=E[fl[now]].from;
}
now=T;
while(now!=S){
E[fl[now]].flow+=flow,E[(fl[now]-^)+].flow-=flow;
now=E[fl[now]].from;
}
return flow;
}
int ISAP(){
memcpy(cur,first,sizeof(first));
BFS();
for(int i=;i<=n;i++) gap[d[i]]++;
int now=S,flow=;
while(d[S]<n){
if(now==T) flow+=augment(),now=S;
bool ok=;
for(int p=cur[now];p;p=E[p].next){
int j=E[p].to;
if(E[p].cap>E[p].flow&&d[j]+==d[now]){
ok=,fl[j]=cur[now]=p,now=j;
break;
}
}
if(!ok){
int minl=n;
for(int p=first[now];p;p=E[p].next){
int j=E[p].to;
if(E[p].cap>E[p].flow&&d[j]+<minl) minl=d[j]+;
}
if(--gap[d[now]]==) break;
gap[d[now]=minl]++;
cur[now]=first[now];
if(now!=S) now=E[fl[now]].from;
}
}
return flow;
}
}net; void data_in()
{
scanf("%d%d",&N,&M);
int w,x,y;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++){
scanf("%d%d",&sco[i][j],&w);
for(int k=;k<=w;k++){
scanf("%d%d",&x,&y);
att[i][j].push_back((XY){x+,y+});
}
}
}
int idx(int x,int y){ return (x-)*M+y; }
void build_net()
{
for(int i=;i<=N;i++)
for(int j=;j<=M;j++){
int id=idx(i,j);
for(int k=;k+j<=M;k++){
gp.add_edge(id+k,id);
gp.rd[id]++;
}
for(int k=;k<att[i][j].size();k++){
int _id=idx(att[i][j][k].x,att[i][j][k].y);
gp.add_edge(id,_id); gp.rd[_id]++;
}
}
gp.n=N*M; gp.topo_sort();
for(int p=;p<=gp.np;p++){
int x=gp.E[p].from,y=gp.E[p].to;
if(gp.topo[x]&&gp.topo[y]) net.add_edge(y,x,net.inf);
}
net.n=N*M+,net.S=net.n-,net.T=net.n;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++) if(gp.topo[idx(i,j)]){
if(sco[i][j]>) net.add_edge(net.S,idx(i,j),sco[i][j]);
else if(sco[i][j]<) net.add_edge(idx(i,j),net.T,-sco[i][j]);
}
}
void work()
{
build_net();
int sum=;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
if(sco[i][j]>&&gp.topo[idx(i,j)]) sum+=sco[i][j];
printf("%d\n",sum-net.ISAP());
}
int main()
{
data_in();
work();
return ;
}

BZOJ 1565 NOI2009 植物大战僵尸 topo+最小割(最大权闭合子图)的更多相关文章

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

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

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

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

  3. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Oracle块修改跟踪功能

    块修改跟踪功能是指使用二进制文件记录数据库中数据库更改的过程. 其目的是提高增量备份操作的性能,因为RMAN可以使用快修改跟踪文件找到上次执行备份操作后被修改的数据块.这可以节省大量时间,因为如果不这 ...

  2. Flask—02-Flask会话控制与模板引擎

    会话控制原理 说明:概念百度说明的很详细,请自行百度 cookie 说明: 由于HTTP协议无状态无连接的特点,导致一个用户在同一网站做连续操作时,需要不断的提供身份信息:为了解决这个问题,我们可以通 ...

  3. iOS | XIB简单应用和注意点

    2018开篇第一篇文章,本文分享一点关于XIB的小知识,对于iOS开发新人来说或许有用. XIB 是 Interface Builder 的图形界面设计文档. 从Xcode 3.0 开始,苹果提供Xi ...

  4. 如何使用Xcode的Targets来管理开发和生产版本的构建

    如何使用Xcode的Targets来管理开发和生产版本的构建 想象一下,你已经完成了应用程序的开发和测试,现在准备提交正式版本.问题是,一些web服务的url指向了测试服务器,同时API密钥被配置用于 ...

  5. ios微信公众号分享回调事件

    IOS手机在分享成功后,回调事件无法正常执行,在回调方法里面加入: setTimeout(function () { //todo }, ); 例如: //分享 Share({ title: &quo ...

  6. (转)阿里巴巴Druid数据源及使用

    原文链接:https://blog.csdn.net/yanguo110/article/details/68944659 第一部分:数据源的集中比较. 目前常用的数据源主要有c3p0.dbcp.pr ...

  7. iptables应用

    192.168.4.119 为本机的ip地址:每条链的规则是由上至下进行匹配,因此我们需要把范围小的规则放在上面以防被覆盖. 1)清空iptables默认规则,并自定义规则 [root@iptable ...

  8. 【mysql学习-1】

    part-1: #use mysql;/*show tables;select * from user;use mysql;show databases;#create database db1; # ...

  9. mac phpstorm 破解方法

    方法参考如下链接: 来源:http://www.cnblogs.com/zyliang/p/6148960.html

  10. Vue 服务器端渲染(一)

    什么是服务器端渲染(SSR)? Vue.js 是构建客户端应用程序的框架.默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM.然而,也可以将同一个组件渲染为服务器端的 HT ...