题目大意:地球与月球间有可容纳无限人的太空站,还有在太空站与星球间按周期行驶的、有固定容量的太空船,每一艘太空船从一个太空站驶往任一太空站耗时均为 1。地球上有一定数量的人,问所有人到月球最少需要多少天。

关键词:分层 最小费用最大流

最大流:把人群看作流。

分层:人们的最优选择会受到其位于哪一天的影响,因此我们关于时间将整个图分层。估计一下最多能用多少天,就分多少层。人们在太空站内可以呆着,因此每天的太空站要向下一天的太空站连容量∞费用1边。太空船运人,因此太空船前一站向下一天的后一站连容量∞费用1边。人类量固定,从S点向第一天的地球连容量为人数费用0边。任意时刻到达月球均可,从每天的月球向T连容量为无穷费用0边。

最小费用:这里的MCMF有些不同:费用不是单位费用,而是绝对费用;最小费用是每次SPFA所得路径的总费用的最大值,而不是和(否则同一天两群人坐船就被算成了两天)。

#include <cstdio>
#include <cstring>
#include <cassert>
#include <queue>
#include <vector>
using namespace std;
//#define test #define LOOP(i,n) for(int i=1; i<=n; i++)
#define S(station, day) station + (day - 1) * TotStation
#define R(x, t) (x - 1) % (t) + 1
#define INF 0x3f3f3f3f
const int MAX_SHIP = , MAX_STOP = , MAX_DAY = , MAX_NODE = MAX_STOP * MAX_DAY; int TotStation, TotShip, TotHuman;
int Cap[MAX_SHIP], Route[MAX_SHIP][MAX_STOP], StopCnt[MAX_STOP]; struct MCMF
{
struct Node;
struct Edge; struct Node
{
Edge *Head, *Prev;
int Dist, Id;
bool Inq;
}; struct Edge
{
int Cap, Cost, OrgCap;
Node *From, *To;
Edge *Next, *Rev;
}; Node _nodes[MAX_NODE];
vector<Edge*> _edges;
int _vCount = , _eCount = ;
Node *Start, *Sink;
int TotFlow, TotCost; void Init(int n, int sId, int tId)
{
_vCount = n;
_eCount = ;
Start = &_nodes[sId], Sink = &_nodes[tId];
TotFlow = TotCost = ;
} Edge *NewEdge()
{
if (_eCount < _edges.size())
return _edges[_eCount];
else
{
_edges.push_back(new Edge());
return _edges[_eCount++];
}
} Edge* AddEdge(Node *from, Node *to, int cap, int cost)
{
Edge *e = NewEdge();
e->From = from;
e->To = to;
e->OrgCap = e->Cap = cap;
e->Cost = cost;
e->Next = e->From->Head;
e->From->Head = e;
return e;
} void Build(int uId, int vId, int cap, int cost)
{
Node *u = uId + _nodes, *v = vId + _nodes;
u->Id = uId;
v->Id = vId;
Edge *edge1 = AddEdge(u, v, cap, cost), *edge2 = AddEdge(v, u, , -cost);
edge1->Rev = edge2;
edge2->Rev = edge1;
} bool SPFA()
{
queue<Node*> q;
LOOP(i, _vCount)
{
_nodes[i].Prev = NULL;
_nodes[i].Dist = INF;
_nodes[i].Inq = false;
}
Start->Dist = ;
q.push(Start);
while (!q.empty())
{
Node *u = q.front();
q.pop();
//printf("SPFA %d Dist %d\n", u->Id, u->Dist);
u->Inq = false;
for (Edge *e = u->Head; e; e = e->Next)
{
if (e->Cap && u->Dist + e->Cost < e->To->Dist)
{
e->To->Dist = u->Dist + e->Cost;
e->To->Prev = e;
if (!e->To->Inq)
{
e->To->Inq = true;
q.push(e->To);
}
}
}
}
return Sink->Prev;
} void Proceed()
{
while (SPFA())
{
assert(Sink->Dist != INF);
int minFlow = INF, curCost = ;
for (Edge *e = Sink->Prev; e; e = e->From->Prev)
minFlow = min(minFlow, e->Cap);
TotFlow += minFlow;
for (Edge *e = Sink->Prev; e; e = e->From->Prev)
{
e->Cap -= minFlow;
e->Rev->Cap += minFlow;
curCost += e->Cost;
}
TotCost = max(TotCost, curCost);
}
}
}g; int Proceed(int totDay)
{
int sId = TotStation*totDay + , tId = TotStation*totDay + ;
g.Init(tId, sId, tId);
g.Build(sId, , TotHuman, );
for (int i = ; i < sId; i += TotStation)
g.Build(i, tId, INF, );
LOOP(station, TotStation)
LOOP(day, totDay - )
g.Build(S(station, day), S(station, day + ), INF, );
LOOP(ship, TotShip)
LOOP(day, totDay - )
g.Build(S(Route[ship][R(day, StopCnt[ship])], day), S(Route[ship][R(day + , StopCnt[ship])], day + ), Cap[ship], );
g.Proceed();
if (g.TotFlow < TotHuman)
return ;
return g.TotCost;
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
scanf("%d%d%d", &TotStation, &TotShip, &TotHuman);
TotStation += ;
LOOP(i, TotShip)
{
scanf("%d%d", i + Cap, i + StopCnt);
LOOP(j, StopCnt[i])
{
scanf("%d", &Route[i][j]);
Route[i][j] += ;
}
}
printf("%d\n", Proceed(MAX_DAY));
return ;
}

注意:

1.要让包括星球在内的太空站的编号从1开始,否则容易晕。

2.最大值不要卡着边设。

luogu2754 星际转移问题 网络流的更多相关文章

  1. luogu2754 星际转移问题

    源向地球连 月球向汇连 每一天往下一天连 飞船上一天与这一天连 枚举答案 #include <iostream> #include <cstring> #include < ...

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

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

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

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

  4. 【BZOJ3993】星际战争(网络流,二分答案)

    [BZOJ3993]星际战争(网络流,二分答案) 题面 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团 ...

  5. Luogu 2469 [SDOI2010]星际竞速 / HYSBZ 1927 [Sdoi2010]星际竞速 (网络流,最小费用流)

    Luogu 2469 [SDOI2010]星际竞速 / HYSBZ 1927 [Sdoi2010]星际竞速 (网络流,最小费用流) Description 10年一度的银河系赛车大赛又要开始了.作为全 ...

  6. Luogu P2754 星际转移问题

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

  7. 网络流24题之星际转移问题(洛谷P2754)

    洛谷 P2754 题目背景 none! 题目描述 由于人类对自然资源的消耗,人们意识到大约在 2300 年之后,地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民.令人意想不到的是,21 ...

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

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

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

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

随机推荐

  1. 记录一个MySQL的问题

    昨天做asp.net mvc程序,用mysql.data.entity.ef6做数据连接. 程序都是正常的,但就是提交数据的时候总是提示 Specified key was too long; max ...

  2. .net core2.0 自定义中间件

    一.中间件(Middleware) 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 二.编写SimpleMiddleware using Microsoft.AspNetCore.Htt ...

  3. javascript执行环境及作用域

    执行环境(execution context,为简单起见,有时也成为“环境”)是javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境 ...

  4. PHP开发笔记(三)关于PHP伪静态的问题总结

    Apache 第一个问题就是关于PHPStudy集成Apache环境下5.5版本以上”No input file specified“问题. 针对TP5框架,以下是.htaccess文件的配置,PHP ...

  5. python--3、 可迭代对象、迭代器、生成器

    可迭代对象 iterable 可直接作用于for循环的对象统称为可迭代对象. 有 list. dict.tuple.set.str等数据类型,还有 generator(包括生成器和带yield的gen ...

  6. 省市区县的sql语句——城市

    /*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...

  7. DHCP 和 MDT 分开服务器的设置方法

    DHCP设置 043:供应商特定信息:01 04 00 00 00 00 FF 060:PXEClient:PXEClient 066:启动服务器主机名:IP 067:启动文件名:\Boot\x86\ ...

  8. CDC之fast->slow (2)

    1 Open-loop solution One potential solution is to assert CDC signals for a period of time that excee ...

  9. 深度学习应用在推荐系统的论文-----A Novel Deep Learning-Based Collaborative Filtering Model for Recommendation System

    1.题目:一种新的基于深度学习的协同过滤推荐系统 2.摘要: 以协同过滤(CF)为基础的模型主要获取用户和项目的交互或者相关性.然而,现有的基于CF的方法只能掌握单一类型的关系,如RBM,它只能获取用 ...

  10. 【编程工具】Vim编辑器的使用

    1.Vim简介   Vim最初起源于古老的贝尔实验室,由"Bram Moolenaar等人"开发,是一个功能强大的文本编辑器,被推崇为类Vi编辑器中最好的一个.   Vim是一个类 ...