Problem Description

度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族。

哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士。

所以这一场战争,将会十分艰难。

为了更好的进攻哗啦啦族,度度熊决定首先应该从内部瓦解哗啦啦族。

第一步就是应该使得哗啦啦族内部不能同心齐力,需要内部有间隙。

哗啦啦族一共有n个将领,他们一共有m个强关系,摧毁每一个强关系都需要一定的代价。

现在度度熊命令你需要摧毁一些强关系,使得内部的将领,不能通过这些强关系,连成一个完整的连通块,以保证战争的顺利进行。

请问最少应该付出多少的代价。

Input

本题包含若干组测试数据。

第一行两个整数n,m,表示有n个将领,m个关系。

接下来m行,每行三个整数u,v,w。表示u将领和v将领之间存在一个强关系,摧毁这个强关系需要代价w

数据范围:

2<=n<=3000

1<=m<=100000

1<=u,v<=n

1<=w<=1000


题目大意:求全局最小割。

题解:就是一标准的Stoer-Wagner算法模板题,邻接表法理论复杂度\(O(nm \log(m))\)。见:全局最小割StoerWagner算法详解

PS:网上绝大部分题解是错误的,反例很容易能找出。但是却能AC,可以看出此次百度之星的出题人非常不认真啊。

代码(6770MS):

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <numeric>
  7. typedef long long LL;
  8. const int MAXV = 3010;
  9. const int MAXE = 100010 * 2;
  10. const int INF = 0x3f3f3f3f;
  11. int head[MAXV], val[MAXV], ecnt;
  12. int to[MAXE], next[MAXE], weight[MAXE];
  13. bool vis[MAXV];
  14. int fa[MAXV], link[MAXV];
  15. int n, m;
  16. void init() {
  17. memset(head + 1, -1, sizeof(int) * n);
  18. memset(link + 1, -1, sizeof(int) * n);
  19. for (int i = 1; i <= n; ++i)
  20. fa[i] = i;
  21. ecnt = 0;
  22. }
  23. void add_edge(int u, int v, int w) {
  24. to[ecnt] = v; weight[ecnt] = w; next[ecnt] = head[u]; head[u] = ecnt++;
  25. to[ecnt] = u; weight[ecnt] = w; next[ecnt] = head[v]; head[v] = ecnt++;
  26. }
  27. int findset(int u) { // 并查集
  28. return u == fa[u] ? u : fa[u] = findset(fa[u]);
  29. }
  30. void merge(int u, int v) {
  31. int p = u;
  32. while (~link[p]) p = link[p];
  33. link[p] = v;
  34. fa[v] = u;
  35. }
  36. int MinimumCutPhase(int cnt, int &s, int &t) {
  37. memset(val + 1, 0, sizeof(int) * n);
  38. memset(vis + 1, 0, sizeof(bool) * n);
  39. std::priority_queue<std::pair<int, int>> que;
  40. t = 1;
  41. while (--cnt) {
  42. vis[s = t] = true;
  43. for (int u = s; ~u; u = link[u]) {
  44. for (int p = head[u]; ~p; p = next[p]) {
  45. int v = findset(to[p]);
  46. if (!vis[v])
  47. que.push(std::make_pair(val[v] += weight[p], v));
  48. }
  49. }
  50. t = 0;
  51. while (!t) {
  52. if (que.empty()) return 0; // 图不连通
  53. auto pa = que.top(); que.pop();
  54. if (val[pa.second] == pa.first)
  55. t = pa.second;
  56. }
  57. }
  58. return val[t];
  59. }
  60. int StoerWagner() {
  61. int res = INF;
  62. for (int i = n, s, t; i > 1; --i) {
  63. res = std::min(res, MinimumCutPhase(i, s, t));
  64. if (res == 0)
  65. break;
  66. merge(s, t);
  67. }
  68. return res;
  69. }
  70. int main() {
  71. while (scanf("%d%d", &n, &m) != EOF) {
  72. init();
  73. for (int i = 0, u, v, w; i < m; ++i) {
  74. scanf("%d%d%d", &u, &v, &w);
  75. add_edge(u, v, w);
  76. }
  77. printf("%d\n", StoerWagner());
  78. }
  79. }

顺便试一下pb_ds库,详见IOI集训队论文《C++的pb_ds库在OI中的应用——于纪平》

pb_ds优先队列学习笔记

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <numeric>
  7. #include <ext/pb_ds/priority_queue.hpp>
  8. typedef long long LL;
  9. /// 都只试了一次,不一定准确
  10. //typedef __gnu_pbds::priority_queue<std::pair<int, int>, std::less<std::pair<int, int>>, __gnu_pbds::binary_heap_tag> PQue; // TLE
  11. //typedef __gnu_pbds::priority_queue<std::pair<int, int>, std::less<std::pair<int, int>>, __gnu_pbds::binomial_heap_tag> PQue; // 7940MS
  12. //typedef __gnu_pbds::priority_queue<std::pair<int, int>, std::less<std::pair<int, int>>, __gnu_pbds::rc_binomial_heap_tag> PQue; // 9204MS
  13. //typedef __gnu_pbds::priority_queue<std::pair<int, int>, std::less<std::pair<int, int>>, __gnu_pbds::pairing_heap_tag> PQue; // 6770MS
  14. typedef __gnu_pbds::priority_queue<std::pair<int, int>, std::less<std::pair<int, int>>, __gnu_pbds::thin_heap_tag> PQue; // 8954MS
  15. const int MAXV = 3010;
  16. const int MAXE = 100010 * 2;
  17. const int INF = 0x3f3f3f3f;
  18. int head[MAXV], val[MAXV], ecnt;
  19. int to[MAXE], next[MAXE], weight[MAXE];
  20. bool vis[MAXV];
  21. int fa[MAXV], link[MAXV];
  22. PQue::point_iterator iter[MAXV];
  23. int n, m;
  24. void init() {
  25. memset(head + 1, -1, sizeof(int) * n);
  26. memset(link + 1, -1, sizeof(int) * n);
  27. for (int i = 1; i <= n; ++i)
  28. fa[i] = i;
  29. ecnt = 0;
  30. }
  31. void add_edge(int u, int v, int w) {
  32. to[ecnt] = v; weight[ecnt] = w; next[ecnt] = head[u]; head[u] = ecnt++;
  33. to[ecnt] = u; weight[ecnt] = w; next[ecnt] = head[v]; head[v] = ecnt++;
  34. }
  35. int findset(int u) { // 并查集
  36. return u == fa[u] ? u : fa[u] = findset(fa[u]);
  37. }
  38. void merge(int u, int v) { // 合并
  39. int p = u;
  40. while (~link[p]) p = link[p];
  41. link[p] = v;
  42. fa[v] = u;
  43. }
  44. int MinimumCutPhase(int cnt, int &s, int &t) {
  45. memset(val + 1, 0, sizeof(int) * n);
  46. memset(vis + 1, 0, sizeof(bool) * n);
  47. PQue que;
  48. for (int i = 1; i <= n; ++i)
  49. iter[i] = 0;
  50. t = 1;
  51. while (--cnt) {
  52. vis[s = t] = true;
  53. for (int u = s; ~u; u = link[u]) {
  54. for (int p = head[u]; ~p; p = next[p]) {
  55. int v = findset(to[p]);
  56. if (!vis[v]) {
  57. if (iter[v] != 0)
  58. que.modify(iter[v], std::make_pair(val[v] += weight[p], v));
  59. else
  60. iter[v] = que.push(std::make_pair(val[v] += weight[p], v));
  61. }
  62. }
  63. }
  64. if (que.empty()) return 0; // 图不连通
  65. t = que.top().second; que.pop();
  66. }
  67. return val[t];
  68. }
  69. int StoerWagner() {
  70. int res = INF;
  71. for (int i = n, s, t; i > 1; --i) {
  72. res = std::min(res, MinimumCutPhase(i, s, t));
  73. if (res == 0)
  74. break;
  75. merge(s, t);
  76. }
  77. return res;
  78. }
  79. int main() {
  80. while (scanf("%d%d", &n, &m) != EOF) {
  81. init();
  82. for (int i = 0, u, v, w; i < m; ++i) {
  83. scanf("%d%d%d", &u, &v, &w);
  84. add_edge(u, v, w);
  85. }
  86. printf("%d\n", StoerWagner());
  87. }
  88. }

HDU 6081 度度熊的王国战略(全局最小割Stoer-Wagner算法)的更多相关文章

  1. HDU 6081 度度熊的王国战略(全局最小割堆优化)

    Problem Description度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族.哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士.所以这一场战争,将会十分艰难.为了更好的进攻 ...

  2. HDU 6081 度度熊的王国战略【并查集/数据弱水题/正解最小割算法】

    链接6081 度度熊的王国战略 Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 32768/132768 K (Java/Others) ...

  3. HDU - 6081 2017百度之星资格赛 度度熊的王国战略

    度度熊的王国战略  Accepts: 644  Submissions: 5880  Time Limit: 40000/20000 MS (Java/Others)  Memory Limit: 3 ...

  4. 2017"百度之星"程序设计大赛 - 资格赛 度度熊的王国战略

    度度熊的王国战略 度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族. 哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士. 所以这一场战争,将会十分艰难. 为了更好的进攻哗啦啦族,度度 ...

  5. 2017"百度之星"程序设计大赛 - 资格赛 1002 度度熊的王国战略

    全局最小割 Stoer-Wagner (SW算法)优化 优化吃藕了,感谢放宽时限,感谢平板电视 (pb_ds) #include <iostream> #include <cstdi ...

  6. 求全局最小割(SW算法)

    hdu3002 King of Destruction Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  7. HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. HDU 6118 度度熊的交易计划(网络流-最小费用最大流)

    度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但 ...

  9. 图的全局最小割的Stoer-Wagner算法及例题

    Stoer-Wagner算法基本思想:如果能求出图中某两个顶点之间的最小割,更新答案后合并这两个顶点继续求最小割,到最后就得到答案. 算法步骤: --------------------------- ...

随机推荐

  1. iOS资源大全中文版

    我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-ios 就是 vsouza 发起维护的 iOS 资源列表,内容包括:框架.组件.测试.App ...

  2. leetcode 6. ZigZag Conversion [java]

    自己写的: if(numRows == 1) return s; int ll = s.length() / 2 + 1; Character tc[] = new Character[numRows ...

  3. BZOJ3155:Preprefix sum(线段树)

    Description Input 第一行给出两个整数N,M.分别表示序列长度和操作个数 接下来一行有N个数,即给定的序列a1,a2,....an 接下来M行,每行对应一个操作,格式见题目描述 Out ...

  4. BZOJ4401:块的计数(乱搞)

    Description 小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树.听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效.当然,无聊的小Y对这种事情毫无兴趣,只是 ...

  5. js 判断元素是否在列表中

    /** * 使用循环的方式判断一个元素是否存在于一个数组中 * @param {Object} arr 数组 * @param {Object} value 元素值 */ function isInA ...

  6. <数据结构与算法分析>读书笔记--函数对象

    关于函数对象,百度百科对它是这样定义的: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.又称仿函数. 听起来确实很难懂,通过搜索我找到一篇 ...

  7. jQuery的extend和fn.extend理解

    参考网址:http://www.cnblogs.com/yuanyuan/archive/2011/02/23/1963287.html http://www.cnblogs.com/xuxiuyu/ ...

  8. 图文列表,关于Simpleadapter

    main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...

  9. springboot 定制错误页面

    项目中经常遇到的异常情况 400-Bad Request 401-Unauthorized If the request already included Authorization credenti ...

  10. 20155206《网络对抗》Web安全基础实践

    20155206<网络对抗>Web安全基础实践 实验后问题回答 (1)SQL注入攻击原理,如何防御 攻击原理:SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查 ...