题目大意

二维平面上有 n 个爆炸桶,i−thi-thi−th爆炸桶位置为 (xi,yi)(x_i, y_i)(xi​,yi​) 爆炸范围为 rir_iri​ ,且需要 cic_ici​ 的价格引爆,求把所有桶引爆所需的钱。

分析

通过求有向图的强连通分量,求出所有爆炸块(满足引爆一个块内的任意一个爆炸桶就可以摧毁这个块内的爆炸桶),然后把所有爆炸块视为一个爆炸桶,价值为爆炸块内的价值最小值,然后重建有向图,将新建的有向图所有入度为 0 的点的价值相加,就是答案。

AC-Code

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 1100; // 点数
  4. const int MAXM = 1000100; // 边数
  5. struct Edge {
  6. int to, next;
  7. } edge[MAXM]; // 只有这里写的是 MAXM
  8. int head[MAXN], tot;
  9. int Low[MAXN], DFN[MAXN], Stack[MAXN], Belong[MAXN]; //Belong 数组的值是 1 ~ scc
  10. int Index, top;
  11. int scc; // 强连通分量的个数
  12. bool Instack[MAXN];
  13. int num[MAXN]; // 各个强连通分量包含点的个数,数组编号 1 ~ scc
  14. // num 数组不一定需要,结合实际情况
  15. void addedge(int u, int v) {
  16. edge[tot].to = v;
  17. edge[tot].next = head[u];
  18. head[u] = tot++;
  19. }
  20. void Tarjan(int u) {
  21. int v;
  22. Low[u] = DFN[u] = ++Index;
  23. Stack[top++] = u;
  24. Instack[u] = true;
  25. for (int i = head[u]; i != -1; i = edge[i].next) {
  26. v = edge[i].to;
  27. if (!DFN[v]) {
  28. Tarjan(v);
  29. if (Low[u] > Low[v])
  30. Low[u] = Low[v];
  31. } else if (Instack[v] && Low[u] > DFN[v])
  32. Low[u] = DFN[v];
  33. }
  34. if (Low[u] == DFN[u]) {
  35. scc++;
  36. do {
  37. v = Stack[--top];
  38. Instack[v] = false;
  39. Belong[v] = scc;
  40. num[scc]++;
  41. } while (v != u);
  42. }
  43. }
  44. void solve(int N) {
  45. memset(DFN, 0, sizeof(DFN));
  46. memset(Instack, false, sizeof(Instack));
  47. memset(num, 0, sizeof(num));
  48. Index = scc = top = 0;
  49. for (int i = 1; i <= N; i++)
  50. if (!DFN[i])
  51. Tarjan(i);
  52. }
  53. void init() {
  54. tot = 0;
  55. memset(head, -1, sizeof(head));
  56. }
  57. struct node {
  58. int x, y, r, c;
  59. bool in_boom(const node &other) const {
  60. return hypot(abs(x - other.x), abs(y - other.y)) <= r;
  61. }
  62. };
  63. node nodeList[1100];
  64. int n;
  65. void init_graph1() {
  66. init();
  67. for (int i = 1; i <= n; ++i) {
  68. for (int j = 1; j <= n; ++j) {
  69. if (i == j) continue;
  70. if (nodeList[i].in_boom(nodeList[j]))
  71. addedge(i, j);
  72. }
  73. }
  74. }
  75. struct Graph {
  76. struct Node {
  77. int deg;
  78. int value;
  79. };
  80. Node node[MAXN];
  81. void init() {
  82. for (int i = 0; i < n + 5; ++i) {
  83. node[i].deg = 0;
  84. node[i].value = INT_MAX;
  85. }
  86. }
  87. void add_edge(int from, int to) {
  88. if (from != to)
  89. node[to].deg++;
  90. }
  91. };
  92. Graph graph;
  93. int ans;
  94. void tp_init() {
  95. graph.init();
  96. for (int i = 1; i <= n; ++i) {
  97. graph.node[Belong[i]].value = min(graph.node[Belong[i]].value, nodeList[i].c);
  98. for (int j = 1; j <= n; ++j) {
  99. if (i == j) continue;
  100. if (nodeList[i].in_boom(nodeList[j]))
  101. graph.add_edge(Belong[i], Belong[j]);
  102. }
  103. }
  104. }
  105. void tp() {
  106. ans = 0;
  107. tp_init();
  108. for (int i = 1; i <= scc; ++i) {
  109. if (graph.node[i].deg == 0) {
  110. ans += graph.node[i].value;
  111. }
  112. }
  113. }
  114. void solve() {
  115. int t;
  116. cin >> t;
  117. for (int ts = 0; ts < t; ++ts) {
  118. cin >> n;
  119. for (int i = 1; i <= n; ++i) {
  120. cin >> nodeList[i].x >> nodeList[i].y >> nodeList[i].r >> nodeList[i].c;
  121. }
  122. init_graph1();
  123. solve(n);
  124. tp();
  125. cout << "Case #" << ts + 1 << ": " << ans << endl;
  126. }
  127. }
  128. int main() {
  129. ios_base::sync_with_stdio(false);
  130. cin.tie(0);
  131. cout.tie(0);
  132. #ifdef ACM_LOCAL
  133. freopen("in.txt", "r", stdin);
  134. freopen("out.txt", "w", stdout);
  135. long long test_index_for_debug = 1;
  136. char acm_local_for_debug;
  137. while (cin >> acm_local_for_debug) {
  138. cin.putback(acm_local_for_debug);
  139. if (test_index_for_debug > 20) {
  140. throw runtime_error("Check the stdin!!!");
  141. }
  142. auto start_clock_for_debug = clock();
  143. solve();
  144. auto end_clock_for_debug = clock();
  145. cout << "Test " << test_index_for_debug << " successful" << endl;
  146. cerr << "Test " << test_index_for_debug++ << " Run Time: "
  147. << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
  148. cout << "--------------------------------------------------" << endl;
  149. }
  150. #else
  151. solve();
  152. #endif
  153. return 0;
  154. }

【HDU5934】Bomb——有向图强连通分量+重建图的更多相关文章

  1. 图的连通性:有向图强连通分量-Tarjan算法

    参考资料:http://blog.csdn.net/lezg_bkbj/article/details/11538359 上面的资料,把强连通讲的很好很清楚,值得学习. 在一个有向图G中,若两顶点间至 ...

  2. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

  3. 有向图强连通分量 Tarjan算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  4. 【转】有向图强连通分量的Tarjan算法

    原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...

  5. 有向图强连通分量的Tarjan算法和Kosaraju算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  6. 算法笔记_144:有向图强连通分量的Tarjan算法(Java)

    目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连 ...

  7. 有向图强连通分量的Tarjan算法及模板

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强联通(strongly connected),如果有向图G的每两个顶点都强联通,称有向图G是一个强联通图.非强联通图有向 ...

  8. 【转载】有向图强连通分量的Tarjan算法

    转载地址:https://www.byvoid.com/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly conn ...

  9. 有向图强连通分量Tarjan算法

    在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间 ...

随机推荐

  1. 10——PHP中的两种数组【索引数组】与【关联数组】

    [索引数组] 用数字作为键名的数组一般叫做索引数组.用字符串表示键的数组就是下面要介绍的关联数组.索引数组的键是整数,而且从0开始以此类推. 索引数组初始化例: <pre name=" ...

  2. 黑客必学之“网页木马webshell”

    摘要: 这节课,我们来了解一下网页的木马,首先我们了解网页木马之前,先来了解一下什么是一句话木马.小马和大马.什么是webshell首先简单说一下webshell,webshell简单来说就是黑客植入 ...

  3. ASP.NET CORE 启动过程及源码解读

    在这个特殊的春节,大家想必都在家出不了们,远看已经到了回城里上班的日子,但是因为一只蝙蝠的原因导致我们无法回到工作岗位,大家可能有的在家远程办公,有些在家躺着看书,有的是在家打游戏:在这个特殊无聊的日 ...

  4. node--非阻塞式I/O,单线程,异步,事件驱动

    1.单线程 不同于其他的后盾语言,node是单线程的,大大节约服务器开支 node不为每个客户创建一个新的线程,仅使用一个线程.通过非阻塞I/O以及 事件驱动机制,使其宏观上看是并发的,可以处理高并发 ...

  5. 使用 custom element 创建自定义元素

    很早我们就可以在 HTML 文档中写 <custome-element></custom-element> 这样的自定义名称标签.但是浏览器对于不认识的标签一律当成一个普通的行 ...

  6. http协议概览

    这里我只是对一些知识进行简单的整理,方便自己理解记忆,还有很多不完善的地方,更多细节,需要查看书籍或者其他文章 http协议的发展过程 HTTP 是基于 TCP/IP 协议的应用层协议.它不涉及数据包 ...

  7. Python -Selenium的安装和调用

    安装selenium步骤: 1.安装pip(cmd命令行管理员方式): pip install pip 也可直接搜索pip,到官网下载安装 2.安装selenium(cmd命令行管理员方式): pip ...

  8. iview中select搜索

    https://www.jianshu.com/p/1c40d7cc440e https://www.cnblogs.com/yun1108/p/10967735.html https://blog. ...

  9. notepad++ 快捷键运行python程序目录存在空格的问题

    通常情况下 cmd /k (python.exe文件所在路径) "$(FULL_CURRENT_PATH)"&PAUSE&EXIT 就ok了,路径里有空格就不一样了 ...

  10. deepin15.11安装N卡驱动,实测!!!(可解决N卡电脑关机卡屏)

    前言:deepin(深度)是一款由武汉深之度公司研发的一款适合国人日常学习的linux系统,其UI精美,美过Mac.它对于中国用户的一个亮点就是QQ微信等国软件傻瓜式安装(类似安卓应用商店安装),如果 ...