bzoj 2561: 最小生成树
2024-08-20 13:16:47
#include<cstdio>
#include<iostream>
#include<cstring>
#define M 100009
#define inf 2139062143
using namespace std;
int n,m,S,tot,cnt=,T,ans,head[],d[],q[*M],next[*M],u[*M],v[*M],a[*M][];
bool bfs()
{
memset(d,,sizeof(d));
int h=,t=;
q[]=S;
d[S]=;
for(;h<t;)
{
h++;
int p=q[h];
for(int i=head[p];i;i=next[i])
if(!d[u[i]]&&v[i])
{
d[u[i]]=d[p]+;
if(d[T])
return ;
t++;
q[t]=u[i];
}
}
return ;
}
int dinic(int s,int f)
{
if(s==T)
return f;
int rest=f;
for(int i=head[s];i&&rest;i=next[i])
if(v[i]&&d[u[i]]==d[s]+)
{
int now=dinic(u[i],min(rest,v[i]));
if(!now)
d[u[i]]=;
v[i]-=now;
v[i^]+=now;
rest-=now;
}
return f-rest;
}
void jia1(int a1,int a2,int a3)
{
cnt++;
next[cnt]=head[a1];
head[a1]=cnt;
u[cnt]=a2;
v[cnt]=a3;
return;
}
void jia(int a1,int a2,int a3)
{
jia1(a1,a2,a3);
jia1(a2,a1,);
return;
}
int main()
{
int s;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&a[i][],&a[i][],&a[i][]);
scanf("%d%d%d",&S,&T,&s);
cnt=;
memset(head,,sizeof(head));
for(int i=;i<=m;i++)
if(a[i][]>s)
{
jia(a[i][],a[i][],);
jia(a[i][],a[i][],);
}
for(;bfs();)
ans+=dinic(S,inf);
cnt=;
memset(head,,sizeof(head));
for(int i=;i<=m;i++)
if(a[i][]<s)
{
jia(a[i][],a[i][],);
jia(a[i][],a[i][],);
}
for(;bfs();)
ans+=dinic(S,inf);
printf("%d\n",ans);
return ;
}
两遍网络流,把比他小的边建起来,最大流就是要删的边数,最大生成树同理。
最新文章
- CSS魔法堂:你真的懂text-align吗?
- 手动创建VS单元测试,显示代码覆盖率
- MyBatis使用总结+整合Spring
- AppWidgetProvider生命周期
- java James
- Pascal 线段树 lazy-tag 模板
- UpdatePanel + 弹出框
- 获取SQL中某一列的类型及精度
- linux之sed的常用操作
- 混用Int与IntPtr导致GetProcAddress始终返回null
- [模板] 匈牙利算法&;&;二分图最小字典序匹配
- 【洛谷P3917】异或序列
- c/c++ 整数除预算保留小数
- Java线上问题排查思路及Linux常用问题分析命令学习
- bash 的相关配置
- Java - 26 Java 数据结构
- 【POJ2631】Roads in the North 树的直径
- jQuery Pagination分页插件
- 群主微信sdk说明地址
- EclEmma安装与使用