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. 2440test 裸机測试 调试不进main 设置改动方法

           2440test没进main函数并非跑飞.bin文件已经烧写到开发板里了的 而是没选择载入文件,导致不能调试程序文件 主要设置例如以下:

  2. hadoop错误java.io.IOException Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try

    错误: java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more go ...

  3. OC协议

    概念:定义了一个接口,其他类负责来实现这些接口.如果你的类实现了一个协议的方法时,则说该类遵循此协议. 非正式协议:非正式协议虽名为协议,但实际上是挂于NSObject上的未实现分类(Unimplem ...

  4. C语言基础知识小总结(1)

    这几天在学习C语言,零零散散的学了十来天,这两天由于家里来了朋友,也没有顾得上写个总结,今天刚把朋友送走,下面就把这十来天的学习情况总结一下,一边在以后好复习与查看. 一.流程控制包括:顺序语句.判断 ...

  5. 【锋利的jQuery】学习笔记01

    第一章 认识jQuery 一.常见的JS库 Prototype 最早的js库之一.把好用JS方法组合,缺点结构松散. Dojo 离线存储API.生成图标组件.矢量图形库.Comet支持.企业级JS库, ...

  6. JS0热身运动

    热身热身小知识点: JS中如何获取元素: 1 通过ID名称来获取:document get element by id  -->document.getElementById() 2 .... ...

  7. Java-hibernate的Hello World

     hibernate 是对jdbc进行轻量级封装的  orm 框架,充当项目的持久层. 要使用 hibernate首先就需要继续配置, 引包:下载hibernate然后加入jar包 同时引入mysql ...

  8. 尽量不要用select into 复制表

    select into 复制表会带来灾难后果,因为只是复制了一个外壳,就像克隆人,有躯体没意识,像原表的主键 外键 约束 触发器 索引都不会被复制过来, 创建一个表:CREATE TABLE [dbo ...

  9. 打印十进制数n 递归

    #include<stdio.h> //printd函数: 打印十进制数n void printd(int n){ ){ putchar('-'); n=-n; } ) printd(n/ ...

  10. cocos2dx 实现不一样的ScrollView

    原来在公司被迫加班加点赶工,用lua实现的版本:http://www.cnblogs.com/mmc1206x/p/4146911.html 后来因我个人的需要, 用C++实现了一个版本. 蓦然回首, ...