【算法】网络流-最大流(dinic)

【题解】

飞船有可承载人数限制,地球为源点,月球为汇点,人像水流一样从以飞船上限为容量的边流向汇点。

人在各站点都面临着上船与否的选择,难以用DP解决最优策略,于是这样的取舍问题可以使用网络流。

其实主要是看数据范围。

构图思路:

由于我们要计算时间,所以使变量T从1开始循环直到运送完毕。

对于每个时间相应加边,从而可以不用在意周期问题。

时间T,对于每个点增加一个T*22+i的分点,并从(T-1)分点向T分点连一条容量为inf的边。

对于飞行路径从(T-1)*22+u向T*22+v连一条容量为p[i]的边。

构图完毕。

最后推一下极限情况下最长的时间,超过了输出0即可。

tot=1,不是0,不是2!

要加当前弧优化,速度会快很多(101ms→2ms)!

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
struct edge{int from,v,flow;}e[];
int S=,T,tot=,first[],q[],a[][],cur[],d[],p[],n,m,k;
void insert(int u,int v,int w)
{
tot++;e[tot].v=v;e[tot].flow=w;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].flow=;e[tot].from=first[v];first[v]=tot;
}
bool bfs()
{
memset(d,-,sizeof(d));
int head=,tail=;q[]=;d[]=;
while(head!=tail)
{
int x=q[head++];if(head>=)head=;
for(int i=first[x];i;i=e[i].from)
if(d[e[i].v]==-&&e[i].flow>)
{
q[tail++]=e[i].v;if(tail>=)tail=;
d[e[i].v]=d[x]+;
}
}
if(d[T*+n+]==-)return ;
return ;
}
int dfs(int x,int a)
{
if(x==T*+n+||a==)return a;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(d[e[i].v]==d[x]+&&(f=dfs(e[i].v,min(a,e[i].flow)))>)
{
e[i].flow-=f;
e[i^].flow+=f;
flow+=f;
a-=f;
if(a==)break;
}
return flow;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=m;i++)
{
scanf("%d%d",&p[i],&a[i][]);
for(int j=;j<=a[i][];j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==-)a[i][j]=n+;
}
}
for(T=;T<=;T++)
{
for(int i=;i<=n+;i++)
{
insert((T-)*+i,T*+i,inf);
}
for(int i=;i<=m;i++)
{
int u=(T-)*+a[i][(T-)%a[i][]+];
int v=T*+a[i][T%a[i][]+];
insert(u,v,p[i]);
}
while(bfs())
{
for(int i=;i<=T*+n+;i++)cur[i]=first[i];
k-=dfs(,inf);
}
if(k<=){printf("%d",T);return ;}
}
printf("");
return ;
}

【CODEVS】1034 家园的更多相关文章

  1. 【wikioi】1034 家园(最大流+特殊的技巧)

    http://wikioi.com/problem/1034/ 太神了这题. 其实一开始我以为是费用流,但是总感觉不对. 原因是我没看到一句话,特定的时刻到达特定的点!! 也就是说,并不是每艘船每次都 ...

  2. [wikioi 1034][CTSC 1999]家园(网络流)

    由于人类对自然的疯狂破坏,人们意识到在大约2300年之后,地球不能再居住了,于是在月球上建立了新的绿地,以便在需要时移民.令人意想不到的是,2177年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须 ...

  3. 【codevs1034】 家园

    http://codevs.cn/problem/1034/ (题目链接) 题意 给出一张n个点的图,有m架飞船按照固定的航班运行,没单位时间移动一次,并且没收航班都有自己的容纳量.问从0号点将K个人 ...

  4. CODEVS_1034 家园 网络流 最大流

    原题链接:http://codevs.cn/problem/1034/ 题目描述 Description 由于人类对自然的疯狂破坏,人们意识到在大约2300年之后,地球不能再居住了,于是在月球上建立了 ...

  5. codevs 3289 花匠

    题目:codevs 3289 花匠 链接:http://codevs.cn/problem/3289/ 这道题有点像最长上升序列,但这里不是上升,是最长"波浪"子序列.用动态规划可 ...

  6. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  7. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  8. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  9. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

随机推荐

  1. Visual C++ 8.0对象布局

    哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...

  2. JavaScript数组去重的四种方法

    今天,洗澡的想一个有趣的问题,使用js给数组去重,我想了四种方法,虽然今天的任务没有完成,5555: 不多说,po代码: //方法一:简单循环去重    Array.prototype.unique1 ...

  3. QMultiMap使用

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QMultiMap使用     本文地址:http://techieliang.com/201 ...

  4. 【第八周】【新蜂】新NABCD

    由小组成员宫成荣撰写 一.小组项目申请时提交的NABCD: 痛点:普通的俄罗斯方块是不现实距离下一级有多远的,我们的游戏能显示距离下一等级游戏有多远.方便玩家体验. nabc: n:能满足大多数玩家的 ...

  5. PAT 甲级 1144 The Missing Number

    https://pintia.cn/problem-sets/994805342720868352/problems/994805343463260160 Given N integers, you ...

  6. application/x-www-form-urlencoded 与 application/json区别

    两种请求方式对服务器端都没什么影响 application/x-www-form-urlencoded方式是比较老的一种方式,这种方式的好处就是浏览器都支持, 在请求发送过程中会对数据进行序列化处理, ...

  7. SSH管理(重启 停止 运行 安装)centos7

    下面整理经常用到管理SSH服务的命令,方便复制哈. SSH服务状态 systemctl status sshd.service SSH运行命令 service sshd start SSH重启命令 s ...

  8. 【Python】Python 猜年龄的游戏

    游戏规则: 允许用户最多尝试3次 每尝试3次后,如果还没猜对,就问用户是否还想继续玩,如果回答Y或y, 就继续让其猜3次,以此往复,如果回答N或n,就退出程序 如何猜对了,就直接退出 age= cou ...

  9. 51nod 1682 中位数计数(差分统计)

    中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数. 现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数. 首先,显 ...

  10. 部分NodeJs

    一.cnmp的操作: 1.cnmp info jquery查询jquery的版本: 2.cnmp install jquery@1.11.1:安装: 3.cnmp list查询所有下载的内容: 4.c ...