ZOJ 3691 Flower(最大流+二分)
来源:互联网 发布:窗帘效果图软件 编辑:程序博客网 时间:2024/06/11 22:03
Gao and his girlfriend's relationship becomes better and better after they flying balloon last week. Thus, Gao wants to play a simple but evil game with his girlfriend at a late night.
The game is simple: there is a three-dimensional space, Gao chooses N points to put flowers. For the point i, it has Fi flowers. And his girlfriend has to move all these flowers topoint 1 altogether. As everyone knows, his girlfriend is not strong like Gao, so she can move flowers from one point to another if and only if the Euclidean distance between two points are smaller or equal to R. In another words, she perhaps has to move flowers to the intermediate point for finally moving all flowers to the point one. In order to stay with his girlfriend as much time as possible, he asks his girlfriend, for the point i, that she can only move out no more than Li flowers (including the points as an intermediate point).
Can you help his poor girlfriend to calculate the minimal R?
Input
There are multiple cases.
For each case, the first line contains an integer N (1 ≤ N ≤ 100), which means there are N points.
For the next N lines, each line contains five integers, Xi, Yi, Zi, Fi and Li. Xi, Yi and Zi are the coordinate of point i (0 ≤ Xi, Yi, Zi ≤ 20000), Fi means there are Fi flowers at the beginning. Li means this point can be moved out no more than Li flowers.
Output
For each test case, it contains one real number indicating the minimal R. The results should be rounded to seven decimal places. If there is no solution for this case, please output -1. Output's absolute error less than 1e-6 will be accepted.
Sample Input
21 1 1 1 12 2 2 2 2
Sample Output
1.7320508
别的点,现在Gao的女朋友要把序号2-n点上的花全部转移到1号点上,一个点上的花要转移到1号点上可以经过别的点中转,
但要符合L[i]的限制,但是Gao的女朋友一次能走的距离是R,如果Gao的女朋友把i号点花转移到j号点上,Gao的女朋友需要
行走的距离是dis(i,j),现在问:Gao的女朋友要完成这项任务需要的最小R,如果完成不了输出-1。
题解:二分答案,建图跑最大流,判断是否满流。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define ll long longusing namespace std;const int MAXN = 410;//点数的最大值const int MAXM = 80010;//边数的最大值const int INF = 0x3f3f3f3f;struct Edge { int to,next,cap,flow;} edge[MAXM]; int tol,n,m,sum;int head[MAXN];int gap[MAXN],dep[MAXN],cur[MAXN];struct Point { double x,y,z; int f,l;} a[MAXN];double d[MAXN][MAXN];void init() { tol = 0; memset(head,-1,sizeof(head));}double dis(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));}void addedge(int u,int v,int w,int rw = 0) { edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}int Q[MAXN];void BFS(int start,int end) { memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0] = 1; int front = 0, rear = 0; dep[end] = 0; Q[rear++] = end; while(front != rear) { int u = Q[front++]; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(dep[v] != -1)continue; Q[rear++] = v; dep[v] = dep[u] + 1; gap[dep[v]]++; } }}int S[MAXN];int sap(int start,int end,int N) { BFS(start,end); memcpy(cur,head,sizeof(head)); int top = 0; int u = start; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; int inser; for(int i = 0; i < top; i++) if(Min > edge[S[i]].cap - edge[S[i]].flow) { Min = edge[S[i]].cap - edge[S[i]].flow; inser = i; } for(int i = 0; i < top; i++) { edge[S[i]].flow += Min; edge[S[i]^1].flow -= Min; } ans += Min; top = inser; u = edge[S[top]^1].to; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = i; break; } } if(flag) { S[top++] = cur[u]; u = v; continue; } int Min = N; for(int i = head[u]; i != -1; i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min + 1; gap[dep[u]]++; if(u != start)u = edge[S[--top]^1].to; } return ans;}bool slove(double R) { init(); int s=0,t=1; for(int i=2; i<=n; i++) { addedge(i,i+n,a[i].l); addedge(s,i,a[i].f); } for(int i=2; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(d[i][j]<=R) { addedge(i+n,j,INF); addedge(j+n,i,INF); } } if(d[i][1]<=R)addedge(i+n,1,INF); } return sum==sap(s,t,2*n);}int main() { //freopen("test.in","r",stdin); while(cin>>n) { sum=0; for(int i=1; i<=n; i++) { scanf("%lf%lf%lf%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].f,&a[i].l); sum+=a[i].f; } sum-=a[1].f; double MaxD=0; for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { d[i][j]=d[j][i]=dis(a[i],a[j]); MaxD=max(MaxD,d[i][j]); } } int flag=0; double l=0.0,r=MaxD; for(int i=0; i<100; i++) { double mid=(l+r)/2; if(slove(mid)) { r=mid; flag=1; } else l=mid; } if(flag) printf("%.7f\n",l); else printf("-1\n"); } return 0;}
- ZOJ 3691 Flower(最大流+二分)
- zoj 3691 Flower(二分+最大流)
- ZOJ Flower (二分+网络流sap 算法)
- zoj 3691 二分+最大流
- ZOJ 3691 Flower
- ZOJ 3691 Flower
- ZOJ 3691 Flower
- ZOJ 3691 Flower 解题报告
- ZOJ Missile 3460 (最大流+二分)
- BNUOJ 28892 Flower (二分+网络流)
- ZOJ 1654 Place the Robots(最大二分匹配)
- zoj 3165(二分图最大点权独立)
- zoj - 2362 - Beloved Sons(二分图最大匹配)
- ZOJ 1364 Machine Schedule (二分图最大匹配)
- zoj 3460 Missile 【二分 + 二分图匹配】 【经典建模】 【二分 + 最大流】
- zoj 3448(最大流)
- nefu500(二分,最大流)
- ZOJ 3760 Treasure Hunting(最大流)
- 关于Win7下局域网互访的问题。
- web挖掘之Apriori算法 JAVA实现
- HDU 1754 多个学生偷改成绩问最高分-线段树-(单点更新,区间查询)
- git教學好網站
- 数据挖掘学习笔记——十大算法之决策树算法、逻辑回归概述
- ZOJ 3691 Flower(最大流+二分)
- Html的表格
- 修改 File Explorer到指定的目录
- javascriptj监听dom元素的变化
- leetcode #242
- 第一篇文章测试
- 数据分析与数据挖掘 入门
- 3.Longest Substring Without Repeating Characters
- leetcode #6 ZigZagConversion