题目描述

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$,表示需要操作这么多次使这条边从图中删除(当边权比指定边大时,这条边就不在考虑范围内了,可以看做是将这条边删除)。源汇点就是指定边的两端点,那么就相当于割掉一些边使源汇点不连通且使割掉边的边权和最小(也就是最小割模型)。利用最小割等于最大流定理直接求最大流即可。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int head[600];
int next[4000];
int to[4000];
int val[4000];
int tot=1;
int n,m;
int S,T;
int id;
int q[600];
int d[600];
int u[1000],v[1000],a[1000];
void add(int x,int y,int z)
{
next[++tot]=head[x];
head[x]=tot;
to[tot]=y;
val[tot]=z;
next[++tot]=head[y];
head[y]=tot;
to[tot]=x;
val[tot]=0;
}
bool bfs(int S,int T)
{
memset(d,-1,sizeof(d));
memset(q,0,sizeof(q));
int l=0,r=0;
q[r++]=S;
d[S]=0;
while(l<r)
{
int now=q[l];
l++;
for(int i=head[now];i;i=next[i])
{
if(val[i]&&d[to[i]]==-1)
{
d[to[i]]=d[now]+1;
q[r++]=to[i];
}
}
}
return d[T]==-1?false:true;
}
int dfs(int x,int maxflow)
{
if(x==T)
{
return maxflow;
}
int used=0;
int nowflow;
for(int i=head[x];i;i=next[i])
{
if(val[i]&&d[to[i]]==d[x]+1)
{
nowflow=dfs(to[i],min(maxflow-used,val[i]));
val[i]-=nowflow;
val[i^1]+=nowflow;
used+=nowflow;
if(nowflow==maxflow)
{
return maxflow;
}
}
}
if(used==0)
{
d[x]=-1;
}
return used;
}
int dinic()
{
int res=0;
while(bfs(S,T))
{
res+=dfs(S,0x3f3f3f3f);
}
return res;
}
int main()
{
scanf("%d%d%d",&n,&m,&id);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u[i],&v[i],&a[i]);
}
S=u[id],T=v[id];
for(int i=1;i<=m;i++)
{
if(a[i]<=a[id]&&i!=id)
{
add(v[i],u[i],a[id]-a[i]+1);
add(u[i],v[i],a[id]-a[i]+1);
}
}
printf("%d",dinic());
}

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. springcloud(十三):Eureka 2.X 停止开发,但注册中心还有更多选择:Consul 使用详解

    在上个月我们知道 Eureka 2.X 遇到困难停止开发了,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka 1.X 系列,另一方面 Spring Cloud 支持很多服务发现的软件, ...

  2. Java的并发及锁

    Java并发编程:用AQS写一把可重入锁 https://blog.csdn.net/zhang5476499/article/details/83796289 线程的同步时可以使一个线程阻塞而等待一 ...

  3. python第二章:数据类型--小白博客

    标准数据类型 Python3 中有六个标准的数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Set(集合) Dictionary(字典) Python3 ...

  4. php 简单的学习GD库绘制图片并传回给前端实现方式

    1.基本的GD库绘制图片汇总 2.后台实现小案例 <?php // $img = imagecreatetruecolor(200,40); // var_dump($img); // 利用GD ...

  5. Django中CBV的执行顺序之源码解析

    浅析Django中的CBV的执行顺序 下图为CBV方式的执行顺序,大概执行流程如下: 其中浅蓝色为在假设自己写的类,即Test类中没有dispatch方法的情况下的执行顺序,当自己的类中有dispat ...

  6. Azure系列2.1.13 —— CloudBlockBlob

    (小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...

  7. hdu1421_搬寝室

    题目:搬寝室 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1421 #include<stdio.h> #include<algor ...

  8. mybatis源码分析(一)------------入门

    在进行源码分析前,先写一个使用mybatis进行开发的demo,方便我们后面进行分析. 一 关于mybatis的demo  pom.xml文件 <project xmlns="http ...

  9. Day 5-7 exec 和元类的创建.

    exec方法 元类 exec(str_command,globals,locals)参数1:字符串形式的命令参数2:全局作用域(字典形式). 如果不指定,默认globals参数3:局部作用(字典形式) ...

  10. flutter-StatelessWidget与StatefulWidget

    StatelessWidget和StatefulWidget是flutter的基础组件,日常开发中自定义Widget都是选择继承这两者之一. 两者的区别在于状态的改变,StatelessWidget面 ...