sgu438:http://acm.sgu.ru/problem.php?contest=0&problem=438

题意:有一条东西向流淌的河,宽为 W,河中有 N 块石头,每块石头的坐标(Xi, Yi)和最大承受人数 Ci 已知。现在有 M 个游客在河的南岸,他们想穿越这条河流,但是每个人每次最远只能跳 D 米,每跳一次耗时 1 秒。问他们能否全部穿越这条河流,如果能,最少需要多长时间。 <= N <= 50, 0 < M <= 50, 0 <= D <= 1000, 0 < W(0<= 1000, 0 < Xi < 1000, 0 < Yi < W, 0 <= Ci <= 1000)。刚看完这题,想当然的认为它是一道最小费用流问题。但是当WA之后我才明白,这题并不是去求一个给定网络的最大流,而是计算这个网络随着时间推移每次能够留出多少流量。我们通过枚举时间的方式来决定在什么时刻能够把所有的人全部送到对岸。注意人是可以从河这岸的任意x坐标出发的。

题解:这是一道费用流。具体的看代码吧。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define inf 100000000
using namespace std;
const int E=;
const int N=;
struct Node{
int v, cap, cost, next; // re记录逆边的下标。
}edge[E];
int n, m;
int ans;
int k, head[N];
int que[N], pre[N], dis[N];
bool vis[N];
void init(){//初始化
k=ans=;
memset(head,-,sizeof(head));
}
void addEdge(int u, int v, int ca, int co){
edge[k].v = v;
edge[k].cap = ca;
edge[k].cost = co;
edge[k].next = head[u];
head[u] = k ++;
edge[k].v = u;
edge[k].cap = ;
edge[k].cost = -co;
edge[k].next = head[v];
head[v] = k ++;
}
bool spfa(){ // 源点为0,汇点为n。
int i;
for(i = ; i <=*m+;i++){
dis[i] = inf;
vis[i] = false;
}
queue<int>Q;
Q.push();
dis[]=;
vis[] = true;
while(!Q.empty()){ // 这里最好用队列,有广搜的意思,堆栈像深搜。
int u = Q.front();
Q.pop();
vis[u]=;
for(i = head[u]; i != -; i = edge[i].next){
int v = edge[i].v;
if(edge[i].cap && dis[v] > dis[u] + edge[i].cost){
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v]){
vis[v] = true;
Q.push(v);
}
}
}
vis[u] = false;
}
if(dis[*m+] == inf) return false;
return true;
}
int end(){
int u, p, sum = inf;
for(u = *m+; u != ; u = edge[p^].v){//0是超级源点
p = pre[u];
sum = min(sum, edge[p].cap);
}
for(u = *m+; u != ; u = edge[p^].v){
p = pre[u];
edge[p].cap -= sum;
edge[p^].cap += sum;
}
return sum;
}
double d,w;
struct Point{
double x;
double y;
int val;
}num[];
int main(){
while(~scanf("%d%d%lf%lf",&m,&n,&d,&w)){
init();//初始化
for(int i=;i<=m;i++){
scanf("%lf%lf%d",&num[i].x,&num[i].y,&num[i].val);
}
for(int i=;i<=m;i++){
if(abs(num[i].y)<=d){
addEdge(,i,n,);
}
}
for(int i=;i<=m;i++){
for(int j=;j<=m;j++){
if(i==j)continue;
double diss=sqrt((num[i].x-num[j].x)*(num[i].x-num[j].x)+(num[i].y-num[j].y)*(num[i].y-num[j].y));
if(diss<=d){
addEdge(i+m,j,inf,);
}
}
if(abs(num[i].y-w)<=d){
addEdge(i+m,*m+,inf,);
}
addEdge(i,i+m,num[i].val,);
}
if(w<=d)addEdge(,*m+,inf,);
int s=n,now=,sum=;
ans=inf;
while(spfa()){
int y=end();
s-=(dis[*m+]-now)*sum+y;
if(s<)s=;
sum+=y;now=dis[*m+];
int temp=now+(int)ceil(s*1.0/sum);
if(temp<ans)ans=temp;
}
if(ans==inf)printf("IMPOSSIBLE\n");
else
printf("%d\n",ans);
}
}

The Glorious Karlutka River =)的更多相关文章

  1. SGU 438 The Glorious Karlutka River =)(最大流)

    Description A group of Mtourists are walking along the Karlutka river. They want to cross the river, ...

  2. SGU438 The Glorious Karlutka River =)(最大流)

    题目大概说有m个人要过一条宽W的河,人最远跳远距离是d,河上有n个垃圾堆,每个垃圾堆都有坐标和同一时间能容纳的人数,问所有人最少要跳几次才能跳到对岸. 又是一题根据时间拆点的最大流. 二分时间建容量网 ...

  3. SGU 438 The Glorious Karlutka River =) ★(动态+分层网络流)

    [题意]有一条东西向流淌的河,宽为W,河中有N块石头,每块石头的坐标(Xi, Yi)和最大承受人数Ci已知.现在有M个游客在河的南岸,他们想穿越这条河流,但是每个人每次最远只能跳D米,每跳一次耗时1秒 ...

  4. SGU 0438 The Glorious Karlutka River =) 动态流

    题目大意:有一条东西向流淌的河,宽为W,河中有N块石头,每块石头的坐标(Xi, Yi)和最大承受人数Ci已知.现在有M个游客在河的南岸,他们想穿越这条河流,但是每个人每次最远只能跳D米,每跳一次耗时1 ...

  5. SGU438_The Glorious Karlutka River =)

    好题,有一些人在河的一边,想通过河里的某些点跳到对岸去.每个点最多只能承受一定数量的人,每人跳跃一次需要消耗一个时间.求所有人都过河的最短时间. 看网上说是用了什么动态流的神奇东东.其实就是最大流吧, ...

  6. SGU438 The Glorious Karlutka River =)

    传送门 sgu原来搬到cf了呀点了好几个链接才找到233 传说中的动态流(?) 反正很暴力就对了QwQ 有容量限制->拆点 对于每个点拆成入点和出点 时间限制->分层 对于每个时刻的每个石 ...

  7. Soj题目分类

    -----------------------------最优化问题------------------------------------- ----------------------常规动态规划 ...

  8. Moon River

    读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html.        昨晚无意中听到了一首英文歌曲,虽不知其意,但是瞬间就被优美的旋律 ...

  9. poj[3093]Margaritas On River Walk

    Description One of the more popular activities in San Antonio is to enjoy margaritas in the park alo ...

随机推荐

  1. Python介绍、环境搭建(Eclipse插件)、第一个程序

    Python介绍 特点 优雅.明白.简单. 适合领域 1. Web站点和各种网络服务 2. 系统工具和脚本 3. 作为"胶水"语言把其它语言开发的模块包装起来方便使用 和其它语言对 ...

  2. LabVIEW的错误簇以及错误处理函数

    我们可以在LabVIEW的Modern>>Array, Matrix & Cluster控件面板找到表示错误簇数据类型的错误输入(Error In)以及错误输出(Error Out ...

  3. Exploring Message Brokers: RabbitMQ, Kafka, ActiveMQ, and Kestrel--reference

    [This article was originally written by Yves Trudeau.] http://java.dzone.com/articles/exploring-mess ...

  4. CentOS7安装使用MySQL

    安装MySQL 添加mysql源 # rpm -Uvh http://repo.mysql.com//mysql57-community-release-el7-7.noarch.rpm 安装mysq ...

  5. python 入门1

    python的历史 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年. 像Per ...

  6. 在ASP.NET中ShowModalDialog+ztree的使用

    .aspx: <script type="text/javascript"> function getReturnValue() { var strResult = w ...

  7. WisDom.Net 框架设计(四) 用户安全

    WisDom.Net  ----用户安全 1.用户单机登录 正如其名这里要求其实就是显示用户只能在一台电脑上登录.防止多处登录,这里简单的说一下实现原理,我们在这里使用session +cookie ...

  8. SqlSugar-事务操作

    一.事务操作实例 特别说明: 1.特别说明:在事务中,默认情况下是使用锁的,也就是说在当前事务没有结束前,其他的任何查询都需要等待 2.ReadCommitted:在正在读取数据时保持共享锁,以避免脏 ...

  9. [序列化] SerializeHelper--序列化操作帮助类 (转载)

    点击下载 SerializeHelper.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.XML序列化2.Json序列化3.SoapFormatter序列化4.BinaryFormatte ...

  10. .NET设计模式(8):适配器模式(Adapter Pattern)

    ):适配器模式(Adapter Pattern)    适配器模式(Adapter Pattern) --.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的 ...