题目描述

Secsa最近对最小生成树问题特别感兴趣。他已经知道如果要去求出一个n个点、m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法。另外,他还知道,某一个图可能有多种不同的最小生成树。例如,下面图 3中所示的都是图 2中的无向图的最小生成树:

当然啦,这些都不是今天需要你解决的问题。Secsa想知道对于某一条无向图中的边AB,至少需要多少代价可以保证AB边在这个无向图的最小生成树中。为了使得AB边一定在最小生成树中,你可以对这个无向图进行操作,一次单独的操作是指:先选择一条图中的边 P1P2,再把图中除了这条边以外的边,每一条的权值都减少1。如图 4所示就是一次这样的操作:

输入

输入文件的第一行有3个正整数n、m、Lab分别表示无向图中的点数、边数、必须要在最小生成树中出现的AB边的标号。
接下来m行依次描述标号为1,2,3…m的无向边,每行描述一条边。每个描述包含3个整数x、y、d,表示这条边连接着标号为x、y的点,且这条边的权值为d。
输入文件保证1<=x,y<=N,x不等于y,且输入数据保证这个无向图一定是一个连通图。

输出

输出文件只有一行,这行只有一个整数,即,使得标号为Lab边一定出现最小生成树中的最少操作次数。

样例输入

4 6 1
1 2 2
1 3 2
1 4 3
2 3 2
2 4 4
3 4 5

样例输出

1

提示

第1个样例就是问题描述中的例子。

1<=n<=500,1<=M<=800,1<=D<10^6

根据$kruskal$的原理,要使一条边能被选取,那么就要保证将边权小于等于这条边的所有边加入到图中后这条边的两端不连通。题目中的操作非常麻烦,我们将它看作是将选定边的边权$+1$,其他边的边权不变。那么就要使一些原本边权小于等于指定边的边的边权比指定边大来使指定边两端点不连通。我们可以建立最小割模型,将边权小于等于指定边的边加入图中(建双向边),流量为$d[lab]-d[i]+1$,表示需要操作这么多次使这条边从图中删除(当边权比指定边大时,这条边就不在考虑范围内了,可以看做是将这条边删除)。源汇点就是指定边的两端点,那么就相当于割掉一些边使源汇点不连通且使割掉边的边权和最小(也就是最小割模型)。利用最小割等于最大流定理直接求最大流即可。

  1. #include<set>
  2. #include<map>
  3. #include<queue>
  4. #include<stack>
  5. #include<cmath>
  6. #include<cstdio>
  7. #include<vector>
  8. #include<bitset>
  9. #include<cstring>
  10. #include<iostream>
  11. #include<algorithm>
  12. #define ll long long
  13. using namespace std;
  14. int head[600];
  15. int next[4000];
  16. int to[4000];
  17. int val[4000];
  18. int tot=1;
  19. int n,m;
  20. int S,T;
  21. int id;
  22. int q[600];
  23. int d[600];
  24. int u[1000],v[1000],a[1000];
  25. void add(int x,int y,int z)
  26. {
  27. next[++tot]=head[x];
  28. head[x]=tot;
  29. to[tot]=y;
  30. val[tot]=z;
  31. next[++tot]=head[y];
  32. head[y]=tot;
  33. to[tot]=x;
  34. val[tot]=0;
  35. }
  36. bool bfs(int S,int T)
  37. {
  38. memset(d,-1,sizeof(d));
  39. memset(q,0,sizeof(q));
  40. int l=0,r=0;
  41. q[r++]=S;
  42. d[S]=0;
  43. while(l<r)
  44. {
  45. int now=q[l];
  46. l++;
  47. for(int i=head[now];i;i=next[i])
  48. {
  49. if(val[i]&&d[to[i]]==-1)
  50. {
  51. d[to[i]]=d[now]+1;
  52. q[r++]=to[i];
  53. }
  54. }
  55. }
  56. return d[T]==-1?false:true;
  57. }
  58. int dfs(int x,int maxflow)
  59. {
  60. if(x==T)
  61. {
  62. return maxflow;
  63. }
  64. int used=0;
  65. int nowflow;
  66. for(int i=head[x];i;i=next[i])
  67. {
  68. if(val[i]&&d[to[i]]==d[x]+1)
  69. {
  70. nowflow=dfs(to[i],min(maxflow-used,val[i]));
  71. val[i]-=nowflow;
  72. val[i^1]+=nowflow;
  73. used+=nowflow;
  74. if(nowflow==maxflow)
  75. {
  76. return maxflow;
  77. }
  78. }
  79. }
  80. if(used==0)
  81. {
  82. d[x]=-1;
  83. }
  84. return used;
  85. }
  86. int dinic()
  87. {
  88. int res=0;
  89. while(bfs(S,T))
  90. {
  91. res+=dfs(S,0x3f3f3f3f);
  92. }
  93. return res;
  94. }
  95. int main()
  96. {
  97. scanf("%d%d%d",&n,&m,&id);
  98. for(int i=1;i<=m;i++)
  99. {
  100. scanf("%d%d%d",&u[i],&v[i],&a[i]);
  101. }
  102. S=u[id],T=v[id];
  103. for(int i=1;i<=m;i++)
  104. {
  105. if(a[i]<=a[id]&&i!=id)
  106. {
  107. add(v[i],u[i],a[id]-a[i]+1);
  108. add(u[i],v[i],a[id]-a[i]+1);
  109. }
  110. }
  111. printf("%d",dinic());
  112. }

BZOJ2521[Shoi2010]最小生成树——最小割的更多相关文章

  1. BZOJ2521:[SHOI2010]最小生成树(最小割)

    Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...

  2. 【BZOJ2521】[Shoi2010]最小生成树 最小割

    [BZOJ2521][Shoi2010]最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算 ...

  3. 【BZOJ-2521】最小生成树 最小割

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 415  Solved: 242[Submit][Statu ...

  4. BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)

    题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...

  5. BZOJ2521 最小生成树 最小割

    5.26 T2:最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法 ...

  6. BZOJ2561最小生成树——最小割

    题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...

  7. BZOJ 2561: 最小生成树(最小割)

    U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...

  8. 【BZOJ2561】最小生成树 最小割

    [BZOJ2561]最小生成树 Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在 ...

  9. bzoj2521 [Shoi2010]最小生成树

    [Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MB Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出 ...

随机推荐

  1. 支持异步同步的分布式CommandBus MSMQ实现 - 支持Session传递、多实例处理

    先上一张本文所描述的适用场景图 分布式场景,共3台server: 前端Server Order App Server Warehouse App Server 功能: 前端Server可以不停的发送C ...

  2. windows 命令行操作 Mysql 数据库

    1 前言 有接手一个新项目,项目中到了 Mysql 数据库 ,这里总结下 windows 命令行操作 Mysql 数据库. 2 Cmd操作数据库 2.1 连接Mysql服务器,命令如下:(root用户 ...

  3. PHP开发web应用安全总结

    XSS跨站脚本 概念:恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的. 危害: 盗取用户COOKIE信息. 跳转 ...

  4. sqlserver2008 传入的表格格式数据流(tds)协议流不正确。

    起因是在sql 2008 里使用 sql prompt 报了一个内部连接致命错误,原本应该想到是数据库连接问题的,奇怪的是能连接上数据库也能查询表仅仅是用不了工具没有智能提示. 几经查询无果,度娘上之 ...

  5. Python之random模块

    random模块 产生随机数的模块 是Python的标准模块,直接导入即可 import random 1)随机取一个整数,使用.randint()方法: import random print(ra ...

  6. Golang开发工具LiteIDE使用方法整理

    安装 参考github的说明 添加GOPATH 创建workspace 创建新文件 运行程序 Liteide中运行程序有两种方式: FR(FileRun)是编译并运行单个文件,可以使用Shift + ...

  7. centos6 yum 安装memcached

    centos6 yum 安装memcached - 像块石头 - 博客园http://www.cnblogs.com/rockee/archive/2012/08/01/2619160.html yu ...

  8. Visual Studio 2010 Shortcuts

    Uploaded by ProNotion, updated on 11/28/2013 by jmb Platform: Windows/ English  PDF    Print   Hide ...

  9. Java中的break,continue关于标签的用法(转载)

    Java的控制循环结构中是没有关键字goto的,这种做法有它的好处,它提高了程序流程控制的可读性,但是也有不好的地方,它降低了程序流程控制的灵活性,所以说,“上帝是公平的”.所以,Java为了弥补这方 ...

  10. mysql数据库在linux上的不同登录方式和权限

    在我的上两篇博文里,一篇是安装,一篇是配置远程登录, 提君博客原创 >>提君博客原创  http://www.cnblogs.com/tijun/  << 所以我的mysql的 ...