SGU438_The Glorious Karlutka River =)
好题,有一些人在河的一边,想通过河里的某些点跳到对岸去。每个点最多只能承受一定数量的人,每人跳跃一次需要消耗一个时间。求所有人都过河的最短时间。
看网上说是用了什么动态流的神奇东东。其实就是最大流吧,不过是一个很有意思的模型。
每递增一个时间,所有的点增加一层,因为有的人可以站在上一个点不走动,最终每个点分别表示河中的某个点在某个特定的时刻。
同时为了保证人数在点的承受范围之内,拆点即可。
一直增加层数,直到最大流达到m为止即可。
召唤代码君:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 55555
#define maxm 9999999
using namespace std; int to[maxm],next[maxm],c[maxm],first[maxn],edge;
int Q[maxm],bot,top,node;
int tag[maxn],d[maxn],TAG=;
int L[],R[];
bool can[maxn],iq[maxn];
int X[],Y[],C[],connect[][];
int n,m,D,W,s,t,ans; int addnode()
{
first[++node]=-;
return node;
} void addedge(int U,int V,int W)
{
edge++;
to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
edge++;
to[edge]=U,c[edge]=,next[edge]=first[V],first[V]=edge;
} bool _input()
{
bot=,top=;
scanf("%d%d%d%d",&n,&m,&D,&W);
for (int i=; i<=n; i++)
{
iq[i]=false;
scanf("%d%d%d",&X[i],&Y[i],&C[i]);
if (C[i]==)
{
i--,n--;
continue;
}
if (Y[i]<=D) Q[++top]=i,iq[i]=true;
}
memset(connect,false,sizeof connect);
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (i!=j && (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])<=D*D)
connect[i][j]=connect[j][i]=true;
while (bot<=top)
{
int cur=Q[bot++];
if (Y[cur]+D>=W) return true;
for (int i=; i<=n; i++)
if (connect[cur][i] && !iq[i]) Q[++top]=i,iq[i]=true;
}
if (D<W) return false;
else return true;
} void build_init_graph()
{
edge=-,node=;
s=addnode(),t=addnode();
for (int i=; i<=n; i++) L[i]=addnode(),R[i]=addnode();
for (int i=; i<=n; i++)
{
addedge(L[i],R[i],C[i]);
if (Y[i]<=D) addedge(s,L[i],C[i]);
if (Y[i]+D>=W) addedge(R[i],t,C[i]);
}
} bool bfs()
{
Q[bot=top=]=t,d[t]=,tag[t]=++TAG,can[t]=false;
while (bot<=top)
{
int cur=Q[bot++];
for (int i=first[cur]; i!=-; i=next[i])
if (c[i^]> && tag[to[i]]!=TAG)
{
tag[to[i]]=TAG,d[to[i]]=d[cur]+;
can[to[i]]=false,Q[++top]=to[i];
if (to[i]==s) return true;
}
}
return false;
} int dfs(int cur,int num)
{
if (cur==t) return num;
int tmp=num,k;
for (int i=first[cur]; i!=-; i=next[i])
if (c[i]> && d[to[i]]==d[cur]- && tag[to[i]]==TAG && !can[to[i]])
{
k=dfs(to[i],min(num,c[i]));
if (k) num-=k,c[i]-=k,c[i^]+=k;
if (num==) break;
}
if (num) can[cur]=true;
return tmp-num;
} int maxflow()
{
int tot=;
while (bfs()) tot+=dfs(s,maxm);
return tot;
} int main()
{
if (!_input()) { puts("IMPOSSIBLE"); return ; }
if (D>=W) { puts(""); return ; }
build_init_graph();
for (ans=; maxflow()<m; ans++)
{
for (int i=; i<=edge; i+=) if (c[i]>) c[i-]+=c[i],c[i]=;
for (int i=; i<=n; i++)
{
L[i]=addnode();
if (Y[i]<=D) addedge(s,L[i],C[i]);
for (int j=; j<=n; j++)
if (connect[i][j]) addedge(R[j],L[i],C[i]);
}
for (int i=; i<=n; i++)
{
R[i]=addnode();
addedge(L[i],R[i],C[i]);
if (Y[i]+D>=W) addedge(R[i],t,C[i]);
}
}
printf("%d\n",ans);
return ;
}
SGU438_The Glorious Karlutka River =)的更多相关文章
- SGU 438 The Glorious Karlutka River =)(最大流)
Description A group of Mtourists are walking along the Karlutka river. They want to cross the river, ...
- SGU438 The Glorious Karlutka River =)(最大流)
题目大概说有m个人要过一条宽W的河,人最远跳远距离是d,河上有n个垃圾堆,每个垃圾堆都有坐标和同一时间能容纳的人数,问所有人最少要跳几次才能跳到对岸. 又是一题根据时间拆点的最大流. 二分时间建容量网 ...
- SGU 438 The Glorious Karlutka River =) ★(动态+分层网络流)
[题意]有一条东西向流淌的河,宽为W,河中有N块石头,每块石头的坐标(Xi, Yi)和最大承受人数Ci已知.现在有M个游客在河的南岸,他们想穿越这条河流,但是每个人每次最远只能跳D米,每跳一次耗时1秒 ...
- The Glorious Karlutka River =)
sgu438:http://acm.sgu.ru/problem.php?contest=0&problem=438 题意:有一条东西向流淌的河,宽为 W,河中有 N 块石头,每块石头的坐标( ...
- SGU 0438 The Glorious Karlutka River =) 动态流
题目大意:有一条东西向流淌的河,宽为W,河中有N块石头,每块石头的坐标(Xi, Yi)和最大承受人数Ci已知.现在有M个游客在河的南岸,他们想穿越这条河流,但是每个人每次最远只能跳D米,每跳一次耗时1 ...
- SGU438 The Glorious Karlutka River =)
传送门 sgu原来搬到cf了呀点了好几个链接才找到233 传说中的动态流(?) 反正很暴力就对了QwQ 有容量限制->拆点 对于每个点拆成入点和出点 时间限制->分层 对于每个时刻的每个石 ...
- Soj题目分类
-----------------------------最优化问题------------------------------------- ----------------------常规动态规划 ...
- Moon River
读书笔记系列链接地址http://www.cnblogs.com/shoufengwei/p/5714661.html. 昨晚无意中听到了一首英文歌曲,虽不知其意,但是瞬间就被优美的旋律 ...
- poj[3093]Margaritas On River Walk
Description One of the more popular activities in San Antonio is to enjoy margaritas in the park alo ...
随机推荐
- restful framework之频率组件
一.频率简介 为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次 二.自定义频率类.自定义频率规则 自定义的逻辑 #(1)取出访问者ip # (2)判断当前ip不在访问字典里,添加进去 ...
- int类型转换的几种方式差异
1.(int)是一种类型转换:当我们觟nt类型到long,float,double,decimal类型,可以使用隐式转换,但是当我们从long类型到int类型就需要使用显式转换,否则会产生编译错误. ...
- Charles工具内存不足时解决办法
Charles runs out of memory After recording for a while Charles will run low on available memory. To ...
- python爬虫beautifulsoup4系列1
前言 以博客园为例,爬取我的博客上首页的发布时间.标题.摘要,本篇先小试牛刀,先了解下它的强大之处,后面讲beautifulsoup4的详细功能. 一.安装 1.打开cmd用pip在线安装beauti ...
- SpringCloud版本问题
兴致勃勃地跟随文档创建并配置Eureka Server工程后,启动准备测试,发现报了java.lang.NoSuchMethodError: org.springframework.boot.buil ...
- 关于MySql数据库主键及索引的区别
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- Netty源码分析第5章(ByteBuf)---->第6节: 命中缓存的分配
Netty源码分析第6章: ByteBuf 第六节: 命中缓存的分配 上一小节简单分析了directArena内存分配大概流程, 知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带 ...
- docker pull下来的镜像放哪儿了?
本机docker版本 docker –version Docker version 1.进入docker 目录 root@Rightsec:~# cd /var/lib/docker root@Rig ...
- 教你用Python解决非平衡数据问题(附代码)
本文为你分享数据挖掘中常见的非平衡数据的处理,内容涉及到非平衡数据的解决方案和原理,以及如何使用Python这个强大的工具实现平衡的转换. 后台回复“不平衡”获取数据及代码~ 前言 好久没有更新自己写 ...
- Nginx是如何配置为 Web 服务器的【转载】
详解 Nginx是如何配置为 Web 服务器的 林涛 发表于:2016-11-29 23:23 分类:WebServer 标签:Nginx,web,web服务器 521次 抽象来说,将 Nginx 配 ...