1、题意:有一些点,点与点之间有保护关系,每个点都有一个权值,求能获得的最大值

2、分析:裸的最大权闭合图,用网络流进行求解,然后我们发现点与点之间的保护关系可能构成环,这样网络流是无法处理的,然后我们拓扑排序去掉那些不能获得的点。注意!!!!这里的环是不能用强连通来强行去掉的,因为——比如有一个点,他两端与它相连的点在环内,那么这个点你也去不掉

最大权闭合图模型:建立源点s和汇点t,将所有正权点连向s,容量为点权,将所有负权点连向t,容量为点权的相反数,原图中的边容量全部设成inf,跑一边最小割,用所有正权点的总和减一下就是答案了

#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 500010
#define inf 214748364

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

namespace dinic{
    struct Edge{
        int from, to, cap, flow, next;
    } G[M];
    int head[M], cur[M], tot;
    int vis[M], d[M];
    int s, t;

    inline void init(){
        tot = -1;
        memset(head, -1, sizeof(head));
    }

    inline void add(int u, int v, int w){
        G[++ tot] = (Edge){u, v, w, 0, head[u]};
        head[u] = tot;
        G[++ tot] = (Edge){v, u, 0, 0, head[v]};
        head[v] = tot;
    }

    inline bool BFS(){
        memset(vis, 0, sizeof(vis));
        queue<int> Q;
        Q.push(s);
        vis[s] = 1;
        d[s] = 0;
        while(!Q.empty()){
            int x = Q.front(); Q.pop();
            for(int i = head[x]; i != -1; i = G[i].next){
                Edge& e = G[i];
                if(e.cap > e.flow && !vis[e.to]){
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    inline int DFS(int x, int a){
        if(x == t || a == 0) return a;
        int flow = 0, f;
        for(int &i = cur[x]; i != -1; i = G[i].next){
            Edge& e = G[i];
            if(d[e.to] == d[x] + 1 && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
                e.flow += f;
                G[i ^ 1].flow -= f;
                flow += f;
                a -= f;
                if(a == 0) break;
            }
        }
        return flow;
    }

    inline int ans(){
        int flow = 0;
        while(BFS()){
            for(int i = s; i <= t; i ++) cur[i] = head[i];
            flow += DFS(s, inf);
        }
        return flow;
    }
}

int val[M];

struct Edge{
    int u, v, next;
} G[M];
int head[M], tot;
int du[M], ok[M];
int n, m;

inline void addedge(int u, int v){
//  printf("%d %d\n", u, v);
    G[++ tot] = (Edge){u, v, head[u]};
    head[u] = tot;
    du[v] ++;
} 

inline void toposort(){
    queue<int> Q;
    for(int i = 1; i <= n * m; i ++) if(!du[i]){
        Q.push(i);
        ok[i] = 1;
    }
    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int i = head[x]; i != -1; i = G[i].next){
            du[G[i].v] --;
            if(!du[G[i].v]){
                Q.push(G[i].v);
                ok[G[i].v] = 1;
            }
            /*puts("fuck");
            printf("%d\n", i);*/
        }

    }
}

int main(){
    n = read(), m = read();
    #define Num(i, j) (i - 1) * m + j
    memset(head, -1, sizeof(head));
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            int num = Num(i, j);
            val[num] = read(); int op = read();
            for(int k = 1; k <= op; k ++){
                int x = read(), y = read();
                x ++; y ++;
                addedge(num, Num(x, y));
            }
            if(j != m) addedge(num + 1, num);
        }
    }
    toposort();
    //puts("fuck");
    dinic::s = 0; dinic::t = n * m + 1;
    dinic::init();
    int res = 0;
    for(int i = 1; i <= n * m; i ++) if(ok[i]){
        if(val[i] > 0) res += val[i], dinic::add(dinic::s, i, val[i]);
        else dinic::add(i, dinic::t, -val[i]);
        for(int j = head[i]; j != -1; j = G[j].next){
            if(ok[G[j].v]){
                dinic::add(G[j].v, i, inf);
            }
        }
    }

    printf("%d\n", res - dinic::ans());
    return 0;
}


BZOJ1565——[NOI2009]植物大战僵尸的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. NYOJ 485

    A*B Problem 描述 设计一个程序求出A*B,然后将其结果每一位相加得到C,如果C的位数大于等于2,继续将C的各位数相加,直到结果是个一位数k. 例如: 6*8=48: 4+8=12: 1+2 ...

  2. PHP的魔法方法__set() __get()

    php的魔法方法__set()与__get() Tags: PHP 我们先来看看官方的文档如何定义他们的: public void __set(string $name, mixed $value); ...

  3. PHP操作MySQL数据库5个步骤

    PHP操作MySQL数据库一般可分为5个步骤:1.连接MySQL数据库服务器:2.选择数据库:3.执行SQL语句:4.关闭结果集:5断开与MySQL数据库服务器连接. 1.用mysql_connect ...

  4. 由12306动态验证码想到的ASP.NET实现动态GIF验证码(附源码)

    背景: 12306网站推出“彩色动态验证码机制”,新版验证码不但经常出现字符叠压,还不停抖动,不少人大呼“看不清”,称“那个验证码,是毕加索的抽象画么!”铁总客服则表示:为了能正常购票只能这样.而多家 ...

  5. C# Memcache分布式缓存简单入门

    什么是Memcache?能做什么? 以下是百度的观点: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问 ...

  6. jquey on

    1.如果你的元素是用clone方法复制出来的,并且,用了on来绑定事件的话,必须在clone的后边添加true,负责你的事件不会生效. 2.必须在on $('.js-liubody').on('cli ...

  7. cout格式化输出

    问题描述: 有N条绳子, 它们的长度分别为Li. 如果从它们中切割出K条相同的绳子的话,这K条绳子每条最长能有多少? (备注:答案保留两位小数) <1>精确到小数点后两位输出 #inclu ...

  8. Jsoup提取文本时保留标签

    使用Jsoup来对html进行处理比较方便,你可能会用它来提取文本或清理html标签.如果你想提取文本时保留标签,可以使用Jsoup.clean方法,参数为html及标签白名单: Jsoup.clea ...

  9. centos上如何安装redis?|centos傻瓜式安装redis教程

    本文介绍centos安装redis,请不要安装2.4.3,是有问题的. 首先安装gcc yum -y install gcc yum -y install gcc-c++ yum install ma ...

  10. php 实用例子:购物车 涉及session与ajax

    login: <div>用户名:<input type="text" id="uid" /></div><div> ...