【二分答案】【最大流】bzoj3130 [Sdoi2013]费用流

二分最大的边的cap,记作Lim。

把所有的边的cap设为min(Lim,cap[i])。

Bob一定会把单位费用加到最大边上。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define EPS 0.000001
#define N 101
#define INF 2147483647.0
#define M 1001
typedef double db;
int n,m,K,S,T;
int v[M<<1],next[M<<1],first[N],en;
db cap[M<<1];
void AddEdge(int U,int V,db Cap)
{
	v[en]=V; cap[en]=Cap; next[en]=first[U]; first[U]=en++;
	v[en]=U; cap[en]=0; next[en]=first[V]; first[V]=en++;
}
queue<int>q;
int d[N],cur[N];
bool bfs()
{
	memset(d,-1,sizeof(int)*(n+1));
	d[S]=0; q.push(S);
	while(!q.empty())
	  {
	  	int U=q.front(); q.pop();
	  	for(int i=first[U];i!=-1;i=next[i])
	  	  if(d[v[i]]==-1&&cap[i]>EPS)
	  	    {
	  	      d[v[i]]=d[U]+1;
	  	      q.push(v[i]);
	  	    }
	  }
	return d[T]!=-1;
}
db dfs(int U,db a)
{
	if(U==T||a<=EPS) return a;
	db Flow=0.0,f;
	for(int &i=cur[U];i!=-1;i=next[i])
	  if(d[v[i]]==d[U]+1&&(f=(dfs(v[i],min(a,cap[i]))))>EPS)
	    {
	      cap[i]-=f;
	      cap[i^1]+=f;
	      Flow+=f;
		  a-=f;
		  if(a<=EPS)
		    break;
	    }
	if(Flow<=EPS) d[U]=-1;
	return Flow;
}
db MaxFlow()
{
	db Flow=0.0,tmp;
	while(bfs())
	  {
	  	memcpy(cur,first,sizeof(int)*(n+1));
	  	while((tmp=dfs(S,INF))>EPS) Flow+=tmp;
	  }
	return Flow;
}
int xs[M],ys[M],zs[M];
int ChuShi;
bool check(db Lim)
{
	memset(first,-1,sizeof(int)*(n+1));
	en=0;
	for(int i=1;i<=m;++i)
	  AddEdge(xs[i],ys[i],min((db)zs[i],Lim));
	db t=MaxFlow();
	return fabs(t-(db)ChuShi)<=EPS?1:0;
}
int main()
{
//	freopen("bzoj3130.in","r",stdin);
	db r=0.0,l=0.0;
	scanf("%d%d%d",&n,&m,&K);
	S=1; T=n;
	memset(first,-1,sizeof(int)*(n+1));
	for(int i=1;i<=m;++i)
	  {
	  	scanf("%d%d%d",&xs[i],&ys[i],&zs[i]);
	  	AddEdge(xs[i],ys[i],(db)zs[i]);
	  	r=max(r,(db)zs[i]);
	  }
	ChuShi=(int)MaxFlow();
	while(r-l>EPS)
	  {
	  	db mid=(l+r)/2.0;
	  	if(check(mid)) r=mid-EPS;
	  	else l=mid+EPS;
	  }
	printf("%d\n%.4lf\n",ChuShi,l*(db)K);
	return 0;
}
时间: 2024-08-28 20:29:31

【二分答案】【最大流】bzoj3130 [Sdoi2013]费用流的相关文章

BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 505[Submit][Status][Discuss] Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都不超

Bzoj3130 [Sdoi2013]费用流

Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1041  Solved: 536 Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负:(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等

BZOJ3130 SDOI2013 费用流 二分法+网络流

题意:给定一张图,求:1.最大流  2.最大流方案中,流量最大的一条边 题解: 第一问裸题 第二问显然Bob要把所有的费用加在流量最大的边上,因此我们二分最长边,每条边的流量改为min{二分出的最大流量,当前边的流量},跑最大流检验. 注意可以是实数流量,比如说: <1,2,3> <3,2,3> <2,4,2> <2,5,2> <2,6,1> 那么加在<1,2>和<3,2>上的流量用2.5最优 #include <q

BZOJ 3130: [Sdoi2013]费用流 网络流+二分

3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1230  Solved: 598[Submit][Status][Discuss] Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.     最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都

【bzoj3130】[Sdoi2013]费用流 二分+网络流最大流

题目描述 Alice和Bob做游戏,给出一张有向图表示运输网络,Alice先给Bob一种最大流方案,然后Bob在所有边上分配总和等于P的非负费用.Alice希望总费用尽量小,而Bob希望总费用尽量大.求两人都采取最优策略的情况下最大流及总费用. 输入 第一行三个整数N,M,P.N表示给定运输网络中节点的数量,M表示有向边的数量,P的含义见问题描述部分.为了简化问题,我们假设源点S是点1,汇点T是点N.接下来M行,每行三个整数A,B,C,表示有一条从点A到点B的有向边,其最大流量是C. 输出 第一

bzoj 3130 [Sdoi2013]费用流(二分,最大流)

Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负:(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量:而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量.最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案.   上图表示

P3305 [SDOI2013]费用流

题目描述 Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识. 最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量. 一个合法的网络流方案必须满足: (1)每条边的实际流量都不超过其最大流量且非负: (2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量:而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量. 最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案. 上图表示了一个最大流问题

【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容

引用题解: 最大流+费用流. 第一问最大流即可. 第二问为“最小费用最大流”. 由题意,这一问的可转化为在上一问的“残量网络”上,扩大一些边的容量,使能从新的图中的最大流为k. 那么易得:对于还有剩余流量的边,走过他们的费用为0.而“增加流量”可变为:对残留网络上的每一条边建一条容量是∞费用是w的边.这表示从这些边走,每一流量的费用为w,这就符合题意了. 最后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,就可进行最小费用最大流算法. #include<cstdio> #includ

Luogu P3305 [SDOI2013]费用流 二分 网络流

题目链接 \(Click\) \(Here\) 非常有趣的一个题目. 关键结论:所有的单位费用应该被分配在流量最大的边上. 即:在保证最大流的前提下,使最大流量最小.这里我们采用二分的方法,每次判断让所有边的流量\(<=mid\)时是否依然有最大流,求得最小的最大流量\(*p\)即可. 为什么会有实数流量呢?其实我也不懂,不过这也造成这个题目需要把流量改成\(double\),有很多细节需要小心谨慎... #include <bits/stdc++.h> using namespace