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. delegate和event

    经过查阅资料和自己的理解整理出来的,欢迎大家指教. delegate和event 何时使用: 异步的时候,比如加载完成通知. 需要回调的时候,比如按钮点击.动画播放结束等. 发送事件通知的时候. 比如 ...

  2. linux常用的压缩与解压缩命令 分类: 学习笔记 linux ubuntu 2015-07-05 19:38 38人阅读 评论(0) 收藏

    1.gzip 压缩 gzip 是压缩文件,压缩之后文件后缀为.gz 用法:gzip 选项 [文件] 2.gunzip 解压 这个命令与gzip的功能刚好相反,这个是解压. 用法 gunzip 选项 [ ...

  3. Android开发之View重写相关API-onLayout,onMeasure,MeasureSpec

     1.onLayout android.view.ViewGroup protected void onLayout(boolean changed, int l, int t, int r, int ...

  4. apache、mod_jk负载均衡与tomcat集群

    最近需要搭建apache和tomcat的集群,实现静态网站直接通过apache访问,动态网站转交给tomcat处理,实现负载均衡和tomcat集群配置. apache安装 wget http://ap ...

  5. 项目打包 tomcat部署

    IDE: IDEA 1.项目maven管理先执行 clean,再执行 compile 2.如果编译compile不成功,则将 C:\Users\Administrator\.m2\repository ...

  6. 解析嵌套json字符串,一个json字符串中嵌套另一个json字符串

    我现在有一个字符串是这样: { "msg": { ", "attrName": "sensorData", "trans ...

  7. 使用DataContractJsonSerializer类将类型实例序列化为JSON字符串和反序列化为实例对象 分类: JSON 前端 2014-11-10 10:20 97人阅读 评论(1) 收藏

    一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...

  8. IIS 上发布ASP.NET5

    原文 http://docs.asp.net/en/latest/publishing/iis.html 1.安装HTTP Platform Handler ,这个是必需的,不然无法通过IIS访问AS ...

  9. SQL几个有点偏的语句

    SQL语句是一种集合操作,就是批量操作,它的速度要比其他的语言快,所以在设计的时候很多的逻辑都会放在sql语句或者存储过程中来实现,这个是一种设计思想.但是今天我们来讨论另外一个话题.Sql页提供了丰 ...

  10. objective-c中字符串长度计算

    我们知道,在c语言中,使用sizeof ()计算在内存中占用的字节数, 引用string.h后,使用strlen()计算字符串的长度(不包含\0). 而在object-c中, "length ...