sgu 438 The Glorious Karlutka River =)(动态网络流)
来源:互联网 发布:config.php下载 编辑:程序博客网 时间:2024/06/05 15:18
题意:m个人在一条宽度为w的河的南岸,现在要到对岸,已知河中有n块石头,每块石头同时只能容纳ci个人,每个人一次都可以跳向距离为d的距离,每次跳跃耗时为1,问m个人全部过河所要花费的最少时间。
解法:不难看出此题具有网络流的各个因素。源-南岸,汇-北岸,中间点-石头,边-距离小于d的石头之间的连线,费用-1,但是m个人可以分多次过河且可以在中间节点停留,因此不可用费用流解法。由于不同时刻两点之间的流量不同,因此不能用一个网络表示整个过程。
动态流的两个基本问题是:“给出时间限制求最大流量”和“给出流量,求从源到汇输送的最小时间”,对于此类问题,我们需要建立封层网络,随着时间的推移在网络中添加新边,在残余网络中继续寻找增广路求解增加流量,由于如存在方案则最多m+n时间内完成,因此只需枚举时间,逐层添加网络来求解最小时间。因为流量限制在点上而不在边上,因此要通过拆点控制每个点的流量限制。
构图:对于时间k增加的网络:如果点i到南岸的距离小于等于d,则连(S,in(i,k),inf),如果i到北岸的距离小于等于d(out(i,k),T,inf),如果i和j距离小于d则连(out(i,k),in(j,k+1),inf)表示从t-1到t时刻的流量变化,边没有流量限制;连(in(i,k),out(i,k),c[i])限制每个时刻每块石头上最大流量。
import java.util.Arrays;import java.util.Scanner;public class River438 {int inf = 1<<28,maxn=10110,maxm=550010;class Sap {class node {int be, ne;int cap, flow;node(int be, int ne, int cap) {this.be = be;this.ne = ne;this.cap = cap;}}int E[]=new int[maxn], len,n;int h[]=new int[maxn], vh[]=new int[maxn], s, t;node buf[]=new node[maxm];void init(int n) {this.n=n;len = 0;Arrays.fill(E, -1);}void addcap(int i, int j, int cap1, int cap2) {buf[len] = new node(j, E[i], cap1);E[i] = len++;buf[len] = new node(i, E[j], cap2);E[j] = len++;}int sap(int index, int maxcap) {if (index == t)return maxcap;int k = maxcap, d, minh = n;// 此次残余流量,某次使用流量,邻居的最小流量for (int i = E[index]; i != -1; i = buf[i].ne) {node no = buf[i];if (no.cap - no.flow > 0) {if (h[index] == h[no.be] + 1) {d = sap(no.be, Math.min(k, no.cap - no.flow));// 下次找到的流量no.flow += d;buf[i ^ 1].flow -= d;// 记录流量变化k -= d;if (h[s] == n || k == 0)// GAPreturn maxcap - k;}minh = Math.min(minh, h[no.be] + 1);// 更新h[index]}}if (k == maxcap) {// 没有找到增广路vh[minh]++;vh[h[index]]--;if (vh[h[index]] == 0)h[s] = n;h[index] = minh;}return maxcap - k;}int solve(int s, int t) {if (s == t)return inf;this.s = s;this.t = t;Arrays.fill(h, 0);Arrays.fill(vh, 0);//for (int i = 0; i < len; i++)//buf[i].flow = 0;int ans = 0;while (h[s] != n)ans += sap(s, inf);return ans;}}Sap sp=new Sap();boolean near(int i,int j){if(i==j)return false;return d*d>=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);}int x[]=new int[maxn],y[]=new int[maxn],c[]=new int[maxn];Scanner scan=new Scanner(System.in);int n,m,d,w,s=10001,t=10002;void run(){n=scan.nextInt();m=scan.nextInt();d=scan.nextInt();w=scan.nextInt();for(int i=1;i<=n;i++){x[i]=scan.nextInt();y[i]=scan.nextInt();c[i]=scan.nextInt();}if(d>=w){System.out.println(1);return;}sp.init(2);int cnt=0,i;for(i=1;i<=m+n;i++){build(i);cnt+=sp.solve(s,t);if(cnt>=m)break;}if(cnt>=m)System.out.println(i+1);elseSystem.out.println("IMPOSSIBLE");}int in(int i,int t){t--;return t*n*2+i;}int out(int i,int t){t--;return t*n*2+i+n;}void build(int k){sp.n+=n*2;for(int i=1;i<=n;i++){if(y[i]<=d)sp.addcap(s,in(i,k),m,0);if(y[i]+d>=w)sp.addcap(out(i,k),t,m,0);sp.addcap(in(i,k),out(i,k),c[i],0);for(int j=1;j<=n;j++)if(near(i,j))sp.addcap(out(i,k),in(j,k+1),m,0);}}public static void main(String[] args) {new River438().run();}}
- SGU 438 The Glorious Karlutka River =) 动态网络流
- sgu 438 The Glorious Karlutka River =)(动态网络流)
- Sgu 438 The Glorious Karlutka River(动态流)
- sgu 438 The Glorious Karlutka River =) 网络流 动态流
- sgu 438 The Glorious Karlutka River 【网络流 分层】
- SGU 438 -- The Glorious Karlutka River =)
- SGU 438. The Glorious Karlutka River =) (网络流,动态流问题)
- SGU 438 The Glorious Karlutka River =) 动态流 最大流
- SGU 438 - The Glorious Karlutka River =)(网络流‘最大流)
- sug438 The Glorious Karlutka River =)(枚举+最大流)
- 【SGU438】The Glorious Karlutka River =) 分层图最大流
- 438. The Glorious Karlutka River =)
- 解题报告 之 SGU438 The Glorious Karlutka River 时间流(动态流)
- 解题报告 之 SGU438 The Glorious Karlutka River
- 动态网络流 SGU 438
- SGU 438 动态流
- SGU 438 动态网络流,SGU挂了,我也不知道A没A
- sgu 326(经典网络流构图)
- 【js特效】一款不错的漂浮悬浮效果
- 开发板启动方式的修改
- 在linux-2.6.26内核中有关于ARM中断实现的详解
- git使用记录
- 设置文本框不能只能输入数字,小数点后只能输入2位
- sgu 438 The Glorious Karlutka River =)(动态网络流)
- 读取SQL SERVER日志及代理日志
- plsql新建数据库,新建用户,导入与导出数据库
- Java可变参数
- PowerDesigner 把Comment写到name中 和把name写到Comment中 pd7以后版本可用
- 【朴素贝叶斯】实战朴素贝叶斯_代码实现_特征选择1
- mysql数据库中text类型长度
- Pentahao Report Desdger 一些经验
- Handel 简介与使用