当前位置: 首页 > news >正文

洛谷P2805 植物大战僵尸

题意:给你一张图,每个节点保护若干节点。

当一个节点不被保护的时候,你就可以gay掉它。

gay每个节点都有收益(可能为负),求最大总收益。

解:首先发现是一个最大权闭合子图。

把保护关系变成被保护,那么gay每个节点就必须gay每个保护它的节点。

然后发现有个小问题:有环。

于是我们tarjan求强连通分量然后删点。最后最大权闭合子图。

这里我删点删的十分暴力......(反正点不多)

注意:删点的时候,如果它权值为正,要在sum里面减去它的权值。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <queue>
  4 #include <cstring>
  5 #include <stack>
  6 
  7 const int N = 1010, M = 1000010, INF = 0x3f3f3f3f;
  8 
  9 struct Edge {
 10     int nex, v, c;
 11 }edge[M << 1], _edge[M]; int top = 1, _top;
 12 
 13 int e[N], d[N], _e[N];
 14 std::queue<int> Q;
 15 std::stack<int> S;
 16 int dfn[N], low[N], num, fr[N], scc_cnt, scc_siz[N], vis[N], val[N], sum;
 17 
 18 void tarjan(int x) {
 19     dfn[x] = low[x] = ++num;
 20     S.push(x);
 21     for(int i = _e[x]; i; i = _edge[i].nex) {
 22         int y = _edge[i].v;
 23         if(!dfn[y]) {
 24             tarjan(y);
 25             low[x] = std::min(low[x], low[y]);
 26         }
 27         else if(!fr[y]) {
 28             low[x] = std::min(low[x], dfn[y]);
 29         }
 30     }
 31     if(low[x] == dfn[x]) {
 32         scc_cnt++;
 33         int y;
 34         do {
 35             y = S.top();
 36             S.pop();
 37             fr[y] = scc_cnt;
 38             scc_siz[scc_cnt]++;
 39         } while(y != x);
 40     }
 41     return;
 42 }
 43 
 44 inline void add(int x, int y, int z) {
 45     top++;
 46     edge[top].v = y;
 47     edge[top].c = z;
 48     edge[top].nex = e[x];
 49     e[x] = top;
 50 
 51     top++;
 52     edge[top].v = x;
 53     edge[top].c = 0;
 54     edge[top].nex = e[y];
 55     e[y] = top;
 56     return;
 57 }
 58 
 59 inline void _add(int x, int y) {
 60     _top++;
 61     _edge[_top].v = y;
 62     _edge[_top].nex = _e[x];
 63     _e[x] = _top;
 64     return;
 65 }
 66 
 67 void del(int x) {
 68     vis[x] = 1;
 69     if(val[x] > 0) {
 70         sum -= val[x];
 71     }
 72     for(int i = e[x]; i; i = edge[i].nex) {
 73         edge[i].c = edge[i ^ 1].c = 0;
 74     }
 75     for(int i = _e[x]; i; i = _edge[i].nex) {
 76         int y = _edge[i].v;
 77         if(!vis[y]) {
 78             del(y);
 79         }
 80     }
 81     e[x] = _e[x] = 0;
 82     return;
 83 }
 84 
 85 inline bool BFS(int s, int t) {
 86     memset(d, 0, sizeof(d));
 87     d[s] = 1;
 88     Q.push(s);
 89     while(!Q.empty()) {
 90         int x = Q.front();
 91         Q.pop();
 92         for(int i = e[x]; i; i = edge[i].nex) {
 93             int y = edge[i].v;
 94             if(!edge[i].c || d[y]) {
 95                 continue;
 96             }
 97             d[y] = d[x] + 1;
 98             Q.push(y);
 99         }
100     }
101     return d[t];
102 }
103 
104 int DFS(int x, int t, int maxF) {
105     if(x == t) {
106         return maxF;
107     }
108     int ans = 0;
109     for(int i = e[x]; i; i = edge[i].nex) {
110         int y = edge[i].v;
111         if(!edge[i].c || d[x] + 1 != d[y]) {
112             continue;
113         }
114         int temp = DFS(y, t, std::min(edge[i].c, maxF - ans));
115         if(!temp) {
116             d[y] = INF;
117         }
118         ans += temp;
119         edge[i].c -= temp;
120         edge[i ^ 1].c += temp;
121         if(ans == maxF) {
122             break;
123         }
124     }
125     return ans;
126 }
127 
128 inline int solve(int s, int t) {
129     int ans = 0;
130     while(BFS(s, t)) {
131         ans += DFS(s, t, INF);
132     }
133     return ans;
134 }
135 
136 int m;
137 inline int id(int x, int y) {
138     return (x - 1) * m + y;
139 }
140 
141 int main() {
142 
143     int n;
144     scanf("%d%d", &n, &m);
145     int s = n * m + 1, t = n * m + 2;
146     for(int i = 1; i <= n; i++) {
147         for(int j = 1; j <= m; j++) {
148             int x, y, z;
149             scanf("%d", &x);
150             val[id(i, j)] = x;
151             if(x > 0) {
152                 add(s, id(i, j), x);
153                 sum += x;
154             }
155             else if(x < 0) {
156                 add(id(i, j), t, -x);
157             }
158             scanf("%d", &z);
159             for(int k = 1; k <= z; k++) {
160                 scanf("%d%d", &x, &y);
161                 x++;
162                 y++;
163                 add(id(x, y), id(i, j), INF);
164                 _add(id(i, j), id(x, y));
165             }
166             if(j < m) {
167                 add(id(i, j), id(i, j + 1), INF);
168                 _add(id(i, j + 1), id(i, j));
169             }
170         }
171     }
172     for(int i = 1; i <= n * m; i++) {
173         if(!dfn[i]) {
174             tarjan(i);
175         }
176     }
177     for(int i = 1; i <= n * m; i++) {
178         if(scc_siz[fr[i]] > 1 && !vis[i]) {
179             del(i);
180         }
181     }
182     printf("%d", sum - solve(s, t));
183     return 0;
184 }
AC代码

 

转载于:https://www.cnblogs.com/huyufeifei/p/10116471.html

相关文章:

  • python之上下文管理器与contextlib
  • 数据类型之函数笔记
  • Flutter redux 进阶
  • 为什么携程要做好持续交付?
  • 变频电源老化测试重要吗?需要做老化测试吗
  • JS笔记1
  • EOS区块链智能合约开发
  • Oracle 11g:bin目录下3个特效权限的文件:root用户所有者 + s权限
  • 如何使用虚拟机来运行linux,并通过ftp来访问linux服务器(多图详细教学)
  • FaaS 的简单实践
  • 身为极客,一道题测出你究竟有多机智!|活动推荐
  • java web service 写入图片到web/img/
  • 通过调研开源基准测试集,解读大数据的应用现状和开源未来
  • 如何保证以太坊DApp本地存储localStorage的安全性?
  • 数据库做分表查询
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • “大数据应用场景”之隔壁老王(连载四)
  • 「译」Node.js Streams 基础
  • Cookie 在前端中的实践
  • node 版本过低
  • NSTimer学习笔记
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • spark本地环境的搭建到运行第一个spark程序
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • vue 配置sass、scss全局变量
  • Vue 重置组件到初始状态
  • 编写高质量JavaScript代码之并发
  • 当SetTimeout遇到了字符串
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 分布式任务队列Celery
  • 配置 PM2 实现代码自动发布
  • 如何利用MongoDB打造TOP榜小程序
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 算法之不定期更新(一)(2018-04-12)
  • 学习笔记TF060:图像语音结合,看图说话
  • 优化 Vue 项目编译文件大小
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 【干货分享】dos命令大全
  • Spring Batch JSON 支持
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #《AI中文版》V3 第 1 章 概述
  • #100天计划# 2013年9月29日
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (007)XHTML文档之标题——h1~h6
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (论文阅读30/100)Convolutional Pose Machines
  • (算法)N皇后问题
  • (转)人的集合论——移山之道
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)