网络流+二分构图
2014-05-13 20:51
375 查看
在一个三维空间中有n个点,每个点的坐标都是正整数。第i个点上面有fi个花朵,每个点最多能运送li朵花到其他的点上,每次只能把一个点上的花朵送到距离其R的点上。现在求出最小的R,使得所有的花朵都能被移动到第一个点上。(zoj)
二分枚举最大值R。并用最大流判断是否满流。
源点0 , 汇点1
i - i+n 容量为li
0 - > i 容量为 fi
i+n - > 1 容量为inf 。
i + n ->j 容量为inf (dist[i][j] <= R)
二分枚举最大值R。并用最大流判断是否满流。
源点0 , 汇点1
i - i+n 容量为li
0 - > i 容量为 fi
i+n - > 1 容量为inf 。
i + n ->j 容量为inf (dist[i][j] <= R)
const int inf = 1000000000 ; const int maxn = 20000 , maxm = 500000 ; struct Edge{ int v , f ,next ; Edge(){} Edge(int _v , int _f , int _next):v(_v) ,f(_f),next(_next){} }; int sourse , meet ; int id ; Edge e[maxm*2 + 10] ; int g[maxn + 10] ; void add(int u , int v , int f){ e[++id] = Edge(v , f ,g[u]) ; g[u] = id ; e[++id] = Edge(u , 0 , g[v]) ; g[v] = id ; } queue <int> que ; bool vis[maxn + 10] ; int dist[maxn + 10] ; void bfs(){ memset(dist , 0 , sizeof(dist)) ; while(! que.empty()) que.pop() ; que.push(sourse) ; vis[sourse] = 1 ; while(! que.empty()){ int u = que.front() ; que.pop() ; for(int i = g[u] ; i ; i = e[i].next){ int v = e[i].v ; if(e[i].f && !vis[v]){ que.push(v) ; dist[v] = dist[u] + 1 ; vis[v] = 1 ; } } } } int dfs(int u , int delta){ if(u == meet) return delta ; int ans = 0 ; for(int i = g[u] ; i && delta ; i = e[i].next){ int v = e[i].v ; if(e[i].f && dist[v] == dist[u] + 1){ int d = dfs(v , min(delta , e[i].f)) ; e[i].f -= d ; e[i^1].f += d ; delta -= d ; ans += d ; } } return ans ; } int maxflow(){ int ans = 0 ; while(1){ memset(vis , 0 , sizeof(vis)) ; bfs() ; if(! vis[meet]) return ans ; ans += dfs(sourse , inf) ; } } void init(){ memset(g , 0 , sizeof(g)) ; id = 1 ; } struct Point{ int x , y , z , f , l ; int dist(Point O){ return (x-O.x)*(x-O.x) + (y-O.y)*(y-O.y) + (z-O.z)*(z-O.z) ; } void read(){ scanf("%d%d%d%d%d",&x,&y,&z,&f,&l) ; } }p[108] ; int n ; int dislen[108][108] ; int all ; int judge(int len){ init() ; int i , j ; sourse = 0 ; meet = 1 ; for(i = 2 ; i <= n ; i++) add(sourse , i , p[i].f) ; for(i = 2 ; i <= n ; i++) add(i , i+n , p[i].l) ; for(i = 2 ; i <= n ; i++){ for(j = i+1 ; j <= n ; j++){ if(dislen[i][j] <= len){ add(i+n , j , inf) ; add(j+n , i , inf) ; } } } for(i = 2 ; i <= n ; i++){ if(dislen[1][i] <= len) add(i+n , 1 , inf) ; } return maxflow() == all ; } int main(){ int i , j ; vector<int> lis ; while(cin>>n){ all = 0 ; for(i = 1 ; i <= n ; i++){ p[i].read() ; all += p[i].f ; } all -= p[1].f ; lis.clear() ; for(i = 1 ; i <= n ; i++){ for(j = i+1 ; j <= n ; j++){ dislen[i][j] = dislen[j][i] = p[i].dist(p[j]) ; lis.push_back(dislen[i][j]) ; } } sort(lis.begin() , lis.end()) ; int S = unique(lis.begin() , lis.end()) - lis.begin() ; int L = 0 , R = S - 1 , M , ans = -1 ; while(L <= R){ M = (L + R) >> 1 ; if(judge(lis[M])){ ans = lis[M] ; R = M - 1 ; } else L = M + 1 ; } if(ans == -1) puts("-1") ; else printf("%.7lf\n" , sqrt(0.0 + ans)) ; } return 0 ; }
相关文章推荐
- 无线Mesh网络的优点总结
- OSI/RM网络7层体系
- OSI/RM网络7层体系
- wpa_supplicant无线网络配置
- tcp状态转移图
- Http的请求头和响应头
- linux c 网络编程:用域名获取IP地址或者用IP获取域名 网络地址转换成整型 主机字符顺序与网络字节顺序的转换
- CENTOS6.2系统日志rsyslog替换默认的日志服务syslog 转载自http://www.phpboy.net/linux/648.html
- android用ImageView显示网络图片
- java 发送http json请求
- iOS系统网络抓包方法
- HTTP POST GET 本质区别详解
- 01-计算机网络概述之协议分层(七层、四层)01-lh
- [转] 解决HttpServletResponse输出的中文乱码问题
- iOS7.1以后企业应用发布需要HTTPS协议,解决步骤
- 【ActionScript 3.0 学习笔记】基于http协议的远程调用
- 安卓 入门扫盲网络资料
- ASIHTTPRequest类库简介和使用说明
- HttpClient+jsoup登录+解析 163邮箱
- VirtualBox的四种网络连接方式