BZOJ2521[Shoi2010]最小生成树——最小割
题目描述
.jpg)
当然啦,这些都不是今天需要你解决的问题。Secsa想知道对于某一条无向图中的边AB,至少需要多少代价可以保证AB边在这个无向图的最小生成树中。为了使得AB边一定在最小生成树中,你可以对这个无向图进行操作,一次单独的操作是指:先选择一条图中的边 P1P2,再把图中除了这条边以外的边,每一条的权值都减少1。如图 4所示就是一次这样的操作:
.jpg)
输入
输出
输出文件只有一行,这行只有一个整数,即,使得标号为Lab边一定出现最小生成树中的最少操作次数。
样例输入
1 2 2
1 3 2
1 4 3
2 3 2
2 4 4
3 4 5
样例输出
提示
第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]最小生成树——最小割的更多相关文章
- BZOJ2521:[SHOI2010]最小生成树(最小割)
Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...
- 【BZOJ2521】[Shoi2010]最小生成树 最小割
[BZOJ2521][Shoi2010]最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算 ...
- 【BZOJ-2521】最小生成树 最小割
2521: [Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 415 Solved: 242[Submit][Statu ...
- BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)
题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...
- BZOJ2521 最小生成树 最小割
5.26 T2:最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法 ...
- BZOJ2561最小生成树——最小割
题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...
- BZOJ 2561: 最小生成树(最小割)
U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...
- 【BZOJ2561】最小生成树 最小割
[BZOJ2561]最小生成树 Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在 ...
- bzoj2521 [Shoi2010]最小生成树
[Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MB Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出 ...
随机推荐
- Docker镜像的修改和自定义
一.docker镜像的更新 (1)启动镜像,写入一些文件或者更新软件 docker run -it 3afd47092a0e[root@44652ba46352 /]# ls (2)更新镜像 dock ...
- Python做windows服务
Python做windows服务(多进程服务),并结束多进程 Python中_,__,__xx__的区别 在注册MyWinService服务时,再使用 "sc delete 服务器名称&qu ...
- 关于function和task的说明
1. 关于函数function调用,总结两个要点: 1. 函数调用一般产生一个值,这个值被赋值给某个变量 2. 函数所返回的值只能是一个,不可以是多个,不能像C语言中采用指针的方式返回多个值.因 ...
- TCP 原理
一.分组交换网络 古老的电话通信,一根电缆,两个用户设备通信 计算机中的两个设备节点通信:分组网络 计算机网络采取分组交换技术,意思就是我有[一块数据]要发给对方,那我会把这[一块数据]分成N份[ ...
- TCP 握手和挥手图解(有限状态机)
1.引言 TCP 这段看过好几遍,老是记不住,没办法找工作涉及到网络编程这块,各种问 TCP .今天好好整理一下握手和挥手过程.献给跟我一样忙碌,找工作的童鞋,欢迎大神批评指正. 2.TCP 的连接建 ...
- vue传参二
<template> <ul> <li v-for="(value,key,index) in list" :key="index" ...
- freemarker数值格式化
语法:number?string(exp) 说明:根据给定的格式化表达式将数值格式化为字符串. 参数:格式化字符串,"0"表示固定占位(至少有这个位数,不足位数用0代替),&quo ...
- Chrome浏览器的版本查看 以及V8 javascript 引擎版本查看
1. 发现chrome浏览器最新版本里面带的V8 引擎 版本号与chrome的版本号有一个关系, 这里简单总结一下: 在地址栏里面输入: chrome://version 即可显示出来 比如我正在使用 ...
- Oracle 条件判断函数decode和case when then案例
--decode条件判断函数 ,,,,,) from dual --需求:不通过连表查询,显示业主类型名称列的值 ,,,'商业','其他') from t_owners --case when the ...
- vue二次实战
vue爬坑之路 npm uninstall 模块名(删除指定模块) https://www.cnblogs.com/wisewrong/p/6255817.html vue快速入门 https://s ...