传送门

不同的时间每个飞船所在的地点不同,给我们启示按照时间构建分层图。

同一个地点 x <x, dayi - 1> -> <x, dayi> 连一条容量为 INF 的边,因为人们可以在一个地点等待

艘飞船的路径 如果 a 的下一站是 b,那么 <a, dayi - 1> -> <b, dayi> 连一条容量为该飞船容量的边,表示可以 a 坐飞船到 b

增加超级源点 s,s 和地球连一条容量为 k 的边

增加超级汇点 t,月球的每一天都和 t 连一条容量为 INF 的边

枚举天数,跑最大流,直到 max_flow == k,输出天数

对于判断是否能到达,用并查集判断连通性

——代码

 #include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 1000001
#define INF 1e9
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, m, k, s, t, cnt, sum;
int f[N], c[N], p[N], b[][], dis[N];
int head[N], to[N << ], next[N << ], val[N << ]; inline int C(int t, int x)
{
return t * (n + ) + x;
} inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
} inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
next[cnt] = head[x];
head[x] = cnt++;
} inline bool bfs()
{
int i, u, v;
std::queue <int> q;
memset(dis, -, sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == -)
{
dis[v] = dis[u] + ;
if(v == t) return ;
q.push(v);
}
}
}
return ;
} inline int dfs(int u, int maxflow)
{
if(u == t) return maxflow;
int v, d, ret = ;
for(int i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == dis[u] + )
{
d = dfs(v, min(val[i], maxflow - ret));
ret += d;
val[i] -= d;
val[i ^ ] += d;
if(ret == maxflow) return ret;
}
}
if(ret ^ maxflow) dis[u] = -;
return ret;
} int main()
{
int i, j, x, y, d;
n = read();
m = read();
k = read();
s = N - , t = N - ;
for(i = ; i <= n + ; i++) f[i] = i;
for(i = ; i <= m; i++)
{
c[i] = read();
p[i] = read();
for(j = ; j < p[i]; j++)
{
b[i][j] = read() + ;
if(j)
{
x = find(b[i][j - ]);
y = find(b[i][j]);
if(x ^ y) f[x] = y;
}
}
}
if(find() ^ find())
{
printf("0\n");
return ;
}
d = ;
memset(head, -, sizeof(head));
add(s, , k);
add(, s, );
while()
{
d++;
for(i = ; i <= n + ; i++)
{
add(C(d - , i), C(d, i), INF);
add(C(d, i), C(d - , i), );
}
for(i = ; i <= m; i++)
{
add(C(d - , b[i][(d - ) % p[i]]), C(d, b[i][d % p[i]]), c[i]);
add(C(d, b[i][d % p[i]]), C(d - , b[i][(d - ) % p[i]]), );
}
add(C(d, ), t, INF);
add(t, C(d, ), );
while(bfs()) sum += dfs(s, INF);
if(sum == k)
{
printf("%d\n", d);
return ;
}
}
}

[luoguP2754] 星际转移问题(最大流)的更多相关文章

  1. 洛谷.2754.星际转移问题(最大流Dinic 分层)

    题目链接 枚举时间 每一个时间点 对于每个之前的位置像当前位置连边,表示这一时刻可待在原地 每艘船 之前时刻位置向当前时刻连边 注意别漏了0时刻src连向earth的边 #include<cst ...

  2. 线性规划与网络流24题●09方格取数问题&13星际转移问题

    ●(做codevs1908时,发现测试数据也涵盖了1907,想要一并做了,但因为“技术”不佳,搞了一上午) ●09方格取数问题(codevs1907  方格取数3) 想了半天,也没成功建好图: 无奈下 ...

  3. Luogu P2754 星际转移问题

    Luogu P2754 星际转移问题 思路 首先,对于地球能否到达月球的问题,考虑使用并查集维护. 对于每艘飞船能够到达的站点,放进一个集合里,若两艘飞船的集合有交集,那么就合并两个集合,最后只要地球 ...

  4. [CTSC1999][网络流24题] 星际转移

    36. [CTSC1999][网络流24题] 星际转移 ★★★☆   输入文件:home.in   输出文件:home.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述: ...

  5. 【网络流24题】No. 13 星际转移问题 (网络判定 最大流)

    [题意] 由于人类对自然资源的消耗, 人们意识到大约在 2300 年之后, 地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民. 令人意想不到的是, 2177 年冬由于未知的原因, 地球 ...

  6. 洛谷 P2754 星际转移问题【最大流】

    判无解的方法非常粗暴:快T了还是没有合法方案,就是无解. 然后枚举答案,对于每一天都建一套太空站,s连地球,t连月球,上一天的太空站连向这一天的太空站,流量均为inf.然后对于每个飞船,上一天的停靠站 ...

  7. 【BZOJ】1927: [Sdoi2010]星际竞速(费用流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1927 题意:n个点的无向图.m条加权边.只能从编号小的到编号大的.可以瞬移,瞬移有时间.每个点只能访 ...

  8. [CTSC1999]【网络流24题】星际转移

    Description 由于人类对自然资源的消耗,人们意识到大约在2300 年之后,地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民.令人意想不到的是,2177 年冬由于未知的原因,地 ...

  9. 【刷题】LOJ 6015 「网络流 24 题」星际转移

    题目描述 由于人类对自然资源的消耗,人们意识到大约在 2300 年之后,地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民.令人意想不到的是,2177 年冬由于未知的原因,地球环境发生了 ...

随机推荐

  1. AutoWidthInput

    import React from 'react'; import PropTypes from 'prop-types'; class AutoWidthInput extends React.Co ...

  2. Python正则表达式计算器流程图

  3. C++容器类-list

    C++ 表(List容器类) 一.概念 头文件:#include <list> 又叫链表,是一种双线性链表,只能顺序访问(从前往后或从后往前) 他不支持随机访问. 二.方法 #includ ...

  4. React支持装饰器

    在用mobx时用到了装饰器,无奈环境不支持装饰器,搜索了半天,网上教程乱七八糟,最后想到了babel官网上肯定有,一搜果然有,安装教程 见Babel官网. 最快捷的教程是官网文档

  5. 【转】如何在VC下检测当前存在的串口及串口热拔插

    当我们在用VS进行串口编程时,在打开串口前,经常想知道当前PC上存在多少个串口,哪些串口可用?哪些串口已经打开了,最好是在一个Combo Box中列表系统当前所有可用的串口以供选择,然而如何获取系统当 ...

  6. Redis 和缓存技术

    Redis 是什么?什么作用?优点和缺点? https://blog.csdn.net/weixin_42295141/article/details/81380633 Redis 的主要功能哨兵+复 ...

  7. linux关于任务计划

    1.一次性任务计划:at 1)添加 在18:16时候重启服务器 at 18:16 >at init 6 >at ctrl+d2)查看 atq 1 Mon Aug 20 21:09:00 2 ...

  8. python入门:in 的用法(它在不在这个字符串里面)

    #!/usr/bin/env python # -*- coding:utf-8 -*- #in 的用法(它在不在这个字符串里面) #ret(返回,译音:ruai特) #给s赋值为字符串“Alex S ...

  9. phpExcel使用方法二

    require_once './phpexcel/PHPExcel.php'; // 首先创建一个新的对象 PHPExcel object $objPHPExcel = new PHPExcel(); ...

  10. 使用fio测试磁盘I/O性能

    简介: fio是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, nu ...