[luogu]P1262 间谍网络 题解
时间:2019-09-21
本文章向大家介绍[luogu]P1262 间谍网络 题解,主要包括[luogu]P1262 间谍网络 题解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
数据范围好小啊(小声)
首先对于环 , 我们可以直接缩成点 , 如果环上的有好多可以收买的间谍的话就找其中要价最低的作为这个缩点后的点的要价
然后怎么处理呐?
我做完以后看到题解区有神仙一个循环就能处理出答案
但是我太菜了自己做的时候并没有想到qaq
所以就用了 DFS
再建一个缩点后的图 , 然后从每一个可以被收买的点上 DFS , 最后看看有没有点没有被搜到就可以了
如果说从一个可以被收买的点 a , 搜的时候找到了另一个已经搜过而且也是可以被收买的点 b
那么就不用买 b 了, 就买个 a 就可以了
当然这个 DFS 复杂度显然 O(n)
代码:
1 #include<cmath> 2 #include<stack> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define APART puts("----------------------") 10 #define debug 1 11 #define FILETEST 1 12 #define inf 100010 13 #define ll long long 14 #define ha 998244353 15 #define INF 0x7fffffff 16 #define INF_T 9223372036854775807 17 #define DEBUG printf("%s %d\n",__FUNCTION__,__LINE__) 18 19 namespace chino{ 20 21 inline void setting(){ 22 #if FILETEST 23 freopen("_test.in", "r", stdin); 24 freopen("_test.me.out", "w", stdout); 25 #endif 26 return; 27 } 28 29 inline int read(){ 30 char c = getchar(), up = c; int num = 0; 31 for(; c < '0' || c > '9'; up = c, c = getchar()); 32 for(; c >= '0' && c <= '9'; num = (num << 3) + (num << 1) + (c ^ '0'), c = getchar()); 33 return up == '-' ? -num : num; 34 } 35 36 int n, m, o; 37 int ans; 38 int cntE, cntR, cntJ, cntT; 39 int val[inf], root[inf]; 40 int belong[inf], in[inf]; 41 int low[inf], dfn[inf], vis[inf]; 42 int head[inf], rehead[inf]; 43 struct Edge{ 44 int to; 45 int next; 46 }e[inf << 1], r[inf << 1]; 47 std::stack <int> S; 48 std::vector <int> V; 49 50 inline void AddEdge 51 (int from, int to, int &cntE, int *head, Edge *e){ 52 ++cntE; 53 e[cntE].to = to; 54 e[cntE].next = head[from]; 55 head[from] = cntE; 56 return; 57 } 58 59 void tarjan(int now){ 60 dfn[now] = low[now] = ++cntJ; 61 S.push(now), vis[now] = 1; 62 for(int i = head[now]; i; i = e[i].next){ 63 int to = e[i].to; 64 if(dfn[to] == 0){ 65 tarjan(to); 66 low[now] = std::min (low[to], low[now]); 67 } else if(vis[to]) 68 low[now] = std::min (low[now], dfn[to]); 69 } 70 if(dfn[now] == low[now]){ 71 int top = S.top(); 72 while(true){ 73 top = S.top(), S.pop(); 74 belong[top] = now; 75 vis[top] = 0; 76 for(int i = head[top]; i; i = e[i].next) 77 AddEdge(now, e[i].to, cntR, rehead, r), ++in[e[i].to]; 78 if(top == now) 79 break; 80 val[now] = std::min (val[now], val[top]); 81 } 82 } 83 return; 84 } 85 86 int DFS(int now, int g, int rooty){ 87 if(vis[now] || (rooty == now && g)) 88 return 0; 89 if(root[now]) 90 ans -= val[now]; 91 root[now] = !g; 92 vis[now] = g; 93 for(int i = head[now]; i; i = e[i].next){ 94 int to = e[i].to; 95 to = belong[to]; 96 DFS(to, 1, rooty); 97 } 98 return 1; 99 } 100 101 inline void fail(int point){ 102 puts("NO"); 103 printf("%d\n", point); 104 exit(0); 105 } 106 107 inline int main(){ 108 n = read(); 109 m = read(); 110 std::fill(val + 1, val + 1 + n, INF); 111 for(int i = 1; i <= m; i++){ 112 int u = read(); 113 val[u] = read(); 114 V.push_back(u); 115 } 116 o = read(); 117 for(int i = 1; i <= o; i++){ 118 int u = read(); 119 int v = read(); 120 AddEdge(u, v, cntE, head, e); 121 } 122 for(int i = 1; i <= n; i++){ 123 if(dfn[i] == 0) 124 tarjan(i); 125 } 126 for(int i = 1; i <= n; i++){ 127 if(in[i] == 0 && val[i] == INF) 128 fail(i); 129 } 130 memset(vis, 0, sizeof vis); 131 for(unsigned int i = 0; i < V.size(); i++) 132 ans += val[belong[V[i]]] * DFS(belong[V[i]], 0, belong[V[i]]); 133 for(int i = 1; i <= n; i++){ 134 if(vis[i] == 0 && val[i] == INF && belong[i] == i) 135 fail(i); 136 } 137 puts("YES"); 138 printf("%d\n", ans); 139 return 0; 140 } 141 142 }//namespace chino 143 144 int main(){return chino::main();}
原文地址:https://www.cnblogs.com/chiarochinoful/p/problem-luogu-P1262.html
- 厚土Go学习笔记 | 14. switch 的条件写的有点灵活,不过风格还是go的一贯风格
- Nodejs学习笔记(十四)— Mongoose介绍和入门
- 厚土Go学习笔记 | 13. 用循环和函数 实现Sqrt(x)
- 代码审计| 这是一款适合练手的漏洞
- 工具| NSE漏洞审计和渗透脚本的demo
- Windows Server 2008 R2 配置Exchange 2010邮件服务器并使用EWS发送邮件
- 厚土Go学习笔记 | 12. if 语句
- 厚土Go学习笔记 | 11. for循环 go语言只有for循环
- 从编译原理看一个解释器的实现
- 厚土Go学习笔记 | 10. 常量 与 数值常量
- Unity应用架构设计(7)——IoC工厂理念先行
- 厚土Go学习笔记 | 09. 类型转换 与 类型推导
- 厚积薄发,拥抱 .NET 2016
- 厚土Go学习笔记 | 08. 零值
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一文掌握PHP Xdebug 本地与远程调试(小结)
- PHP生成随机码的思路与方法实例探索
- CI框架教程之优化验证码机制详解【验证码辅助函数】
- ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
- PHP中str_split()函数的用法讲解
- 微信JSSDK分享功能图文实例详解
- spring-boot-route(八)整合mybatis操作数据库
- PHP扩展Swoole实现实时异步任务队列示例
- ThinkPHP框架下微信支付功能总结踩坑笔记
- spring-boot-route(九)整合JPA操作数据库
- spring-boot-route(十)多数据源切换
- spring-boot-route(十一)数据库配置信息加密
- PHP中number_format()函数的用法讲解
- php7新特性的理解和比较总结
- PHP之认识(二)关于Traits的用法详解