题目描述

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。

然后考虑Kruscal求最小生成树的方法,一条边一定出现在最小生成树上,等价于所有边权小于等于它的边不能使得这两个端点连通。

于是转化为最小割问题。

对于每条长度小于等于给定的边,连容量为 给定长度-当前长度+1 的边,然后跑最小割即可。

#include <queue>
#include <cstdio>
#include <cstring>
#define N 510
#define K 810
#define M 100010
using namespace std;
queue<int> q;
int x[K] , y[K] , z[K] , head[N] , to[M] , val[M] , next[M] , cnt = 1 , s , t , dis[N];
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = z , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
int main()
{
int n , m , p , i , ans = 0;
scanf("%d%d%d" , &n , &m , &p);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d" , &x[i] , &y[i] , &z[i]);
s = x[p] , t = y[p];
for(i = 1 ; i <= m ; i ++ )
if(i != p && z[i] <= z[p])
add(x[i] , y[i] , z[p] - z[i] + 1);
while(bfs()) ans += dinic(s , 1 << 30);
printf("%d\n" , ans);
return 0;
}

最新文章

  1. bzoj3380+3381+3382+3383 Usaco2004 Open
  2. nginx中配置pathinfo模式示例
  3. 作为WEB工程师,我们是不是应该积极的推进一下用户浏览器的使用体验?
  4. Linux双网卡绑定和解除绑定的实现
  5. 4K Block Size的Device和 Aligned IO
  6. 【整理修订】Android.mk详解
  7. JSOP
  8. 试试Navicat和Axere RP Pro吧
  9. good page
  10. Redis监控工具,命令和调优
  11. python面试题一个字符串是否由重复的子字符串组成
  12. [Go] golang互斥锁mutex
  13. Oracle Data Provider for .Net classes文档
  14. 微信小程序——使用vue构建小程序【外传】
  15. python 全栈开发,Day30(纸牌游戏,异常和错误,异常处理)
  16. 牛客网暑期ACM多校训练营(第一场)I Substring
  17. MySQL主从数据库配置
  18. oracle建表,设置主键,修改属性等
  19. maven nexus linux私服搭建
  20. Metasploit没有db_autopwn命令的解决办法

热门文章

  1. 洛谷 U3348 A2-回文数
  2. java入门第一章——java开发入门
  3. python爬虫之路——初识函数与控制语句
  4. Codeforces 786E. ALT 最小割+倍增
  5. cdoj 414 八数码 (双向bfs+康拓展开,A*)
  6. UVA 246 10-20-30 10-20-30游戏 模拟+STL双端队列deque
  7. 【转】iOS开发-文件管理(一)
  8. Spark集锦
  9. jQ实现JSON.stringify(obj)方法
  10. [bzoj]3436 小K的农场