Codeforces--653D--Delivery Bears(二分+最大流)



Delivery Bears

Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

Niwel is a little golden bear. As everyone knows, bears live in forests, but Niwel got tired of seeing all the trees so he decided to move to the city.

In the city, Niwel took on a job managing bears to deliver goods. The city that he lives in can be represented as a directed graph with n nodes and m edges.
Each edge has a weight capacity. A delivery consists of a bear carrying weights with their bear hands on a simple path from node 1 to node n.
The total weight that travels across a particular edge must not exceed the weight capacity of that edge.

Niwel has exactlyx bears. In the interest of fairness, no bear can rest, and the weight that each bear carries must be exactly
the same. However, each bear may take different paths if they like.

Niwel would like to determine, what is the maximum amount of weight he can deliver (it‘s the sum of weights carried by bears). Find the maximum weight.

Input

The first line contains three integers nm and x (2?≤?n?≤?50, 1?≤?m?≤?500, 1?≤?x?≤?100?000) —
the number of nodes, the number of directed edges and the number of bears, respectively.

Each of the following m lines contains three integers aibi and ci (1?≤?ai,?bi?≤?nai?≠?bi, 1?≤?ci?≤?1?000?000).
This represents a directed edge from node ai to bi with
weight capacity ci. There are no self loops and no multiple edges from one city to the other city. More formally, for each i and j that i?≠?j it‘s
guaranteed that ai?≠?aj or bi?≠?bj.
It is also guaranteed that there is at least one path from node 1 to node n.

Output

Print one real value on a single line — the maximum amount of weight Niwel can deliver if he uses exactly x bears. Your answer will be considered correct if its absolute
or relative error does not exceed 10?-?6.

Namely: let‘s assume that your answer is a, and the answer of the jury is b. The checker program will
consider your answer correct if .

Sample Input

Input

4 4 3
1 2 2
2 4 1
1 3 1
3 4 2

Output

1.5000000000

Input

5 11 23
1 2 3
2 3 4
3 4 5
4 5 6
1 3 4
2 4 5
3 5 6
1 4 2
2 5 3
1 5 2
3 2 30

Output

10.2222222222
题意:n个点m条边,x只小熊,小熊要把东西从1点运到n点,但是每条边都有一定的权值,小熊运的东西不能超过边对应的权值,并且每只小熊搬运的东西都是一样的,每只小熊可能会选择不一样的路,求搬运的最多的货物有多少
明显是要二分的,每次枚举一个货物的重量,然后跑一边最大流,判断所有的小熊是否都可以到达,建图的时候可以加一步转化,把边权转化为最多通过的小熊的数量,最大流的返回值应该大于等于x
精度要考虑清楚,还是不要while了,时间会很长,直接跑100遍for循环,一直折半很快就可以把一个比较大的数变小,100次for足够把精度误差缩小
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 6000
#define MAXM 1000000
#define INF 0x3f3f3f3f
int n,m,x,cnt;
int vis[MAXN],dis[MAXN],cur[MAXN],head[MAXN];
int u[MAXN],v[MAXN],cap[MAXN];
struct node
{
	int u,v,cap,flow,next;
}edge[MAXM];
void add(int a,int b,int c)
{
	node E={a,b,c,0,head[a]};
	edge[cnt]=E;
	head[a]=cnt++;
	node E1={b,a,0,0,head[b]};
	edge[cnt]=E1;
	head[b]=cnt++;
}
bool BFS(int s,int t)
{
	queue<int>q;
	memset(vis,0,sizeof(vis));
	memset(dis,-1,sizeof(dis));
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			node E=edge[i];
			if(E.cap>E.flow&&!vis[E.v])
			{
				vis[E.v]=1;
				dis[E.v]=dis[E.u]+1;
				if(E.v==t) return true;
				q.push(E.v);
			}
		}
	}
	return false;
}
int DFS(int x,int a,int t)
{
	if(a==0||x==t) return a;
	int flow=0,f;
	for(int &i=cur[x];i!=-1;i=edge[i].next)
	{
		node &E=edge[i];
		if(dis[x]+1==dis[E.v]&&(f=DFS(E.v,min(E.cap-E.flow,a),t))>0)
		{
			a-=f;
			flow+=f;
			edge[i].flow+=f;
			edge[i^1].flow-=f;
			if(a==0) break;
		}
	}
	return flow;
}
int MAXflow(int s,int t)
{
	int flow=0;
	while(BFS(s,t))
	{
		memcpy(cur,head,sizeof(head));
		flow+=DFS(s,INF,t);
	}
	return flow;
}
bool judge(double mid)
{
	cnt=0;
	memset(head,-1,sizeof(head));
	for(int i=0;i<m;i++)
	add(u[i],v[i],(int)min(x*1.0,cap[i]*1.0/mid));
	return MAXflow(1,n)>=x;
}
int main()
{
	while(scanf("%d%d%d",&n,&m,&x)!=EOF)
	{

		memset(u,0,sizeof(u));
		memset(v,0,sizeof(v));
		memset(cap,0,sizeof(cap));
		for(int i=0;i<m;i++)
		scanf("%d%d%d",&u[i],&v[i],&cap[i]);
		double l=0,r=1e10,mid;
		double ans=0;
		for(int i=0;i<=100;i++)
		{
			mid=(l+r)/2;
			if(judge(mid))
			{
				ans=mid;
				l=mid;
			}
			else
			r=mid;
		}
		printf("%.10lf\n",ans*x);
	}
	return 0;
}

时间: 2024-10-22 21:47:27

Codeforces--653D--Delivery Bears(二分+最大流)的相关文章

Codeforces 653D Delivery Bears(最大流)

题目大概说有一张n个点m条边的简单有向图,每条边只能允许一定总量的货物通过.要让x只熊从1点到n点运送货物,每只熊都要运送且运送的货物重量都一样,求该重量的最大值. 二分重量判断是否成立. 如果已知重量,那么每条边能通过多少只熊就知道了,就是边的容量除以重量.而判断x只熊能否走到1到n就是用最大流判定. 那么这题就OK了——不过要注意一下精度——还有会爆int!..这我真的想不到.. 1 #include<cstdio> 2 #include<cstring> 3 #include

POJ 2455 Secret Milking Machine(二分+最大流)

POJ 2455 Secret Milking Machine 题目链接 题意:一个无向图,要求有T条不重复道路可以从1走到t,问道路中最大边的最小值可以是多少 思路:二分+最大流,二分长度,连起边,注意是无向图,所以反向边是有容量的,然后源点和1连容量t,n和汇点连容量是t 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespa

UValive3268 Jamie&#39;s Contact Groups(二分+最大流)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1269 Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The c

poj2455Secret Milking Machine【二分 + 最大流】

Secret Milking Machine Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9129   Accepted: 2742 Description Farmer John is constructing a new milking machine and wishes to keep it secret as long as possible. He has hidden in it deep within

HDU 3036 拆点二分最大流

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 584    Accepted Submission(s): 117 Problem Description R's girl friend D is on military training somewhere near Harbin. She feels bad ever

POJ 2112 Optimal Milking(二分+最大流)

POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每个机器能容纳m个奶牛,问所有奶牛都能挤上奶,那么走的距离最大的奶牛的最小值是多少 思路:明显的二分+最大流,注意floyd求出的距离矩阵最大值可能不止200,所以二分的上限要注意 代码: #include <cstdio> #include <cstring> #include <queue> #include <algori

NEFUOJ 500 二分+最大流

http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=500 description 在这个信息化的时代,网购成为了最流行的购物方式,比起在大街上,顶着烈日寻找需要的商品,大多数人更愿意坐在家里,点击下鼠标,来找到喜欢的商品,并完成购物.尽管网购还有很多安全问题,但是接受网购的人还是越来越多.网购的轻松,使得许多人淡忘了货物配送的烦恼.其实货物配送才是网购最重要的环节,货物送不到,一切都免谈.货物的配送还耗费了大量的资金,很多

uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。

/** 题目: uvalive 3231 Fair Share 公平分配问题 链接:https://vjudge.net/problem/UVALive-3231 题意:有m个任务,n个处理器,每个任务有两个候选处理器,只要其中一个运行,该任务就能执行. 不同任务的两个候选处理器,至少有一个不同. 求任务数最多的那个处理器所分配的任务数尽量少. 思路:二分+最大流 左边是任务,s->u,cap = 1. 如果任务u和u的候选处理器v,u->v, cap = 1. 右边是处理器,二分mi.所有处

POJ 2289 Jamie&#39;s Contact Groups (二分+最大流)

题目大意: 有n个人,可以分成m个组,现在给出你每个人可以去的组的编号,求分成的m组中人数最多的组最少可以有多少人. 算法讨论: 首先喷一下这题的输入,太恶心了. 然后说算法:最多的最少,二分的字眼.二分什么,因为我们说的是组的人,所以要对组的流出量进行二分.其余的都连流量为1的边,然后对“小组”点的流出量二分连边,最后跑最大流判断 是否等于N即可.还是蛮简单的. Codes: 1 #include <cstdio> 2 #include <cstring> 3 #include