好题,有一些人在河的一边,想通过河里的某些点跳到对岸去。每个点最多只能承受一定数量的人,每人跳跃一次需要消耗一个时间。求所有人都过河的最短时间。

看网上说是用了什么动态流的神奇东东。其实就是最大流吧,不过是一个很有意思的模型。

每递增一个时间,所有的点增加一层,因为有的人可以站在上一个点不走动,最终每个点分别表示河中的某个点在某个特定的时刻。

同时为了保证人数在点的承受范围之内,拆点即可。

一直增加层数,直到最大流达到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 =)的更多相关文章

  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. The Glorious Karlutka River =)

    sgu438:http://acm.sgu.ru/problem.php?contest=0&problem=438 题意:有一条东西向流淌的河,宽为 W,河中有 N 块石头,每块石头的坐标( ...

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

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

  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. 优化JDBC开发

    一.元数据 元数据:数据库.表.列的定义信息 1.DataBaseMetaData对象 getURL():返回一个String类对象,代表数据库的URL. getUserName():返回连接当前数据 ...

  2. 【Unity Shader】(七) ------ 复杂的光照(下)

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题.              [Unity Sha ...

  3. TPO-19 C2 Cafeteria's Food Policy

    TPO-19 C2 Cafeteria's Food Policy 第 1 段 1.Listen to a conversation between a student and the directo ...

  4. 【SIKIA计划】_11_Unity动画插件-DOTween笔记

    [插值移动]using DG.Tweening;public class GetStart:MomoBehaviour{ public Vector3 myValue = new Vector3(0, ...

  5. Unity学习笔记(5):动态加载Prefab

    第一种方法,从Resources文件夹读取Prefab Assets/Resources文件夹是Unity中的一个特殊文件夹,在博主当前的认知里,放在这个文件夹里的Prefab可以被代码动态加载 直接 ...

  6. 百度地图在移动端下click无效的解决方案

    这是由于百度地图在移动端屏蔽了click事件,在网上找到一种方法,利用touchClick方法来模拟click事件,代码如下(需要JQ插件): //给jquery添加touchClick方法 (fun ...

  7. 九九乘法表的python复习

    九九开始的复习 这周复习之前的学的知识关于range函数,gormat函数,print的使用总结一下 从一个小例子开始,开始我的回顾吧, 大家都是从那个九九乘法表开始的数学之旅,从一一得一,开始了我们 ...

  8. (2) English Learning

      数词 数词有基数词和序数词两种.英语的数词可以作句子的主语.宾语.表语和定语. 基数词:表示数目的词叫基数词. 1. 英语中常用的基数词有:除了图片上的,还有以下一些 1000→one(a) th ...

  9. 华为笔试——C++最高分问题

    题目介绍:现在输入一组数据,写入学生的考试分数.已知学生数为N,学生编号为1到N,且0<N<=30000,每个学生都有一个分数:操作数为M且0<M<5000.输入第一行为N M ...

  10. IOS statusBarStyle 设置

    在项目info.plist文件中有 View controller-based status bar appearance 属性. 当设置为NO时 通过 [UIApplication sharedAp ...