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

Output
对于每组测试数据,输出最小需要的代价。

Sample Input
2 1
1 2 1
3 3
1 2 5
1 2 4
2 3 3

Sample Output
1
3

题意

如上

题解

做法1.求全局最小割,由于点多边少,得用SW+堆优化(nmlogm)

做法2.S=1,随机T,求最小割,考虑到两个集合a和b,1肯定在a或b集合,也就是说随机的点只要在另外一个集合上,就有可能跑出最小割,特别要注意的是如果2999+1或者2998+2,会被卡到,所以可以特判掉这两种情况,另外>=3个点的概率还是挺高的(雾)

代码

SW+堆优化8080ms

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn=;
  5. const int maxm=2e5+;
  6. const int INF=0x3f3f3f3f;
  7.  
  8. int FIR[maxn],TO[maxm],NEXT[maxm],W[maxm],tote;
  9. bool vis[maxn];
  10. int F[maxn],link[maxn],wage[maxn];
  11. int n,m;
  12.  
  13. void add(int u,int v,int w)
  14. {
  15. TO[tote]=v;
  16. W[tote]=w;
  17. NEXT[tote]=FIR[u];
  18. FIR[u]=tote++;
  19.  
  20. TO[tote]=u;
  21. W[tote]=w;
  22. NEXT[tote]=FIR[v];
  23. FIR[v]=tote++;
  24. }
  25. int Find(int x)
  26. {
  27. return x==F[x]?x:F[x]=Find(F[x]);
  28. }
  29. void Join(int u,int v)
  30. {
  31. int p=u;
  32. while(link[p]!=-)p=link[p];
  33. link[p]=v;
  34. F[v]=u;
  35. }
  36. int MinCut(int cnt,int &s,int &t)
  37. {
  38. memset(wage,,sizeof wage);
  39. memset(vis,false,sizeof vis);
  40. priority_queue< pair<int,int> >q;
  41. t=;
  42. while(--cnt)
  43. {
  44. vis[s=t]=true;
  45. for(int u=s;u!=-;u=link[u])
  46. {
  47. for(int p=FIR[u];p!=-;p=NEXT[p])
  48. {
  49. int v=Find(TO[p]);
  50. if(!vis[v])
  51. q.push(make_pair(wage[v]+=W[p],v));
  52. }
  53. }
  54. t=;
  55. while(!t)
  56. {
  57. if(q.empty())return ;
  58. pair<int,int> pa=q.top();q.pop();
  59. if(wage[pa.second]==pa.first)
  60. t=pa.second;
  61. }
  62. }
  63. return wage[t];
  64. }
  65. int Stoer_Wagner()
  66. {
  67. int res=INF;
  68. for(int i=n,s,t;i>;i--)
  69. {
  70. res=min(res,MinCut(i,s,t));
  71. if(res==)break;
  72. Join(s,t);
  73. }
  74. return res;
  75. }
  76. void init()
  77. {
  78. tote=;
  79. for(int i=;i<=n;i++)FIR[i]=link[i]=-,F[i]=i;
  80. }
  81. int main()
  82. {
  83. while(scanf("%d%d",&n,&m)!=EOF)
  84. {
  85. init();
  86. for(int i=,u,v,w;i<m;i++)
  87. {
  88. scanf("%d%d%d",&u,&v,&w);
  89. add(u,v,w);
  90. }
  91. printf("%d\n",Stoer_Wagner());
  92. }
  93. return ;
  94. }

随机算法2402ms

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int maxn=;
  5. const int maxm=2e5+;//至少总M*2
  6. const int INF=0x3f3f3f3f;
  7.  
  8. int TO[maxm],CAP[maxm],NEXT[maxm],tote;
  9. int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[],u[maxm],v[maxm],w[maxm];
  10. int n,m,S,T;
  11.  
  12. void add(int u,int v,int cap)
  13. {
  14. //printf("i=%d %d %d %d\n",tote,u,v,cap);
  15. TO[tote]=v;
  16. CAP[tote]=cap;
  17. NEXT[tote]=FIR[u];
  18. FIR[u]=tote++;
  19.  
  20. TO[tote]=u;
  21. CAP[tote]=;
  22. NEXT[tote]=FIR[v];
  23. FIR[v]=tote++;
  24. }
  25. void bfs()
  26. {
  27. memset(gap,,sizeof gap);
  28. memset(d,,sizeof d);
  29. ++gap[d[T]=];
  30. for(int i=;i<=n;++i)cur[i]=FIR[i];
  31. int head=,tail=;
  32. q[]=T;
  33. while(head<=tail)
  34. {
  35. int u=q[head++];
  36. for(int v=FIR[u];v!=-;v=NEXT[v])
  37. if(!d[TO[v]])
  38. ++gap[d[TO[v]]=d[u]+],q[++tail]=TO[v];
  39. }
  40. }
  41. int dfs(int u,int fl)
  42. {
  43. if(u==T)return fl;
  44. int flow=;
  45. for(int &v=cur[u];v!=-;v=NEXT[v])
  46. if(CAP[v]&&d[u]==d[TO[v]]+)
  47. {
  48. int Min=dfs(TO[v],min(fl,CAP[v]));
  49. flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^]+=Min;
  50. if(!fl)return flow;
  51. }
  52. if(!(--gap[d[u]]))d[S]=n+;
  53. ++gap[++d[u]],cur[u]=FIR[u];
  54. return flow;
  55. }
  56. int ISAP()
  57. {
  58. bfs();
  59. int ret=;
  60. while(d[S]<=n)ret+=dfs(S,INF);
  61. return ret;
  62. }
  63. void init()
  64. {
  65. tote=;
  66. memset(FIR,-,sizeof FIR);
  67. }
  68. int main()
  69. {
  70. srand(time(NULL));
  71. while(scanf("%d%d",&n,&m)!=EOF)
  72. {
  73. int wage[maxn]={};
  74. for(int i=;i<m;i++)
  75. {
  76. scanf("%d%d%d",&u[i],&v[i],&w[i]);
  77. wage[u[i]]+=w[i];
  78. wage[v[i]]+=w[i];
  79. }
  80. int sj[maxn];
  81. for(int i=;i<n;i++)sj[i]=i+;
  82. random_shuffle(sj+,sj+n);
  83. int ans=1e9;
  84. for(int i=;i<=n;i++)ans=min(ans,wage[i]);
  85. if(n!=)for(int i=;i<m;i++)ans=min(ans,wage[u[i]]+wage[v[i]]-*w[i]);
  86. S=;
  87. for(int i=;i<=min(,n-);i++)
  88. {
  89. T=sj[i];
  90. init();
  91. for(int j=;j<m;j++)
  92. add(u[j],v[j],w[j]),add(v[j],u[j],w[j]);
  93. ans=min(ans,ISAP());
  94. }
  95. printf("%d\n",ans);
  96. }
  97. return ;
  98. }

HDU 6081 度度熊的王国战略(全局最小割堆优化)的更多相关文章

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

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

  2. HDU 6081 度度熊的王国战略(全局最小割Stoer-Wagner算法)

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

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

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

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

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

  8. 全局最小割StoerWagner算法详解

    前言 StoerWagner算法是一个找出无向图全局最小割的算法,本文需要读者有一定的图论基础. 本文大部分内容与词汇来自参考文献(英文,需***),用兴趣的可以去读一下文献. 概念 无向图的割:有无 ...

  9. SW算法求全局最小割(Stoer-Wagner算法)

    我找到的唯一能看懂的题解:[ZZ]最小割集Stoer-Wagner算法 似乎是一个冷门算法,连oi-wiki上都没有,不过洛谷上竟然有它的模板题,并且2017百度之星的资格赛还考到了.于是来学习一下. ...

随机推荐

  1. mysql 字符串数字转换

    1 方法一:SELECT CAST('123' AS SIGNED); 2 方法二:SELECT CONVERT('123',SIGNED); 3 方法三:select '123'+1

  2. 自己写一个spring boot starter

    https://blog.csdn.net/liuchuanhong1/article/details/55057135

  3. Linux:条件变量

    条件变量:     条件变量本身不是锁!但它也可以造成线程阻塞.通常与互斥锁配合使用.给多线程提供一个会合的场所. 主要应用函数:     pthread_cond_init函数     pthrea ...

  4. JQuery+Ajax实现唯一性验证、正则

    //唯一性验证 public function Only(){ //实例化模型层 $model = new User(); $res = $model->Only(); echo $res; } ...

  5. List,Set,Map集合的遍历方法

    List的三种实现:ArrayList(数组)  LinkedList(链表)  Vector(线程安全) List集合遍历方法: List<String> list = new Arra ...

  6. C# 监测每个方法的执行次数和占用时间(测试3)

    原文:http://www.cnblogs.com/RicCC/archive/2010/03/15/castle-dynamic-proxy.html 在Nuget引用 Castle.Dynamic ...

  7. Linux基本操作指令

    Linux操作指令 到达当前用户目录:cd ~ 获得管理员权限执行:sudo 解压缩:tar -zxf XXX.tgz 安装包:dpkg -i XXX.deb 通过链接下载文件:wget  http: ...

  8. spring 解耦

    spring之后不用在类中new一个实体,而是在类中申明接口类:当真正使用的时候是注入相应的实现类,要什么类注入申明类:那么这样就面向接口编程了:耦合度大大降低: 同时spring有面向切面编程,其实 ...

  9. 2018面向对象程序设计(Java)第1周学习指导及要求

    2018面向对象程序设计(Java) 第1周学习指导及要求(2018.8.24-2018.9.2)   学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 简单了解Java特点及历 ...

  10. Animator

    [Animator] 1.State Machine Behaviours A State Machine Behaviour is a special class of script. In a s ...