LuoguP2754 [CTSC1999]家园(分层图,最大流)
题目背景
none!
题目描述
由于人类对自然资源的消耗,人们意识到大约在 2300 年之后,地球就不能再居住了。于是在月球上建立了新的绿地,以便在需要时移民。令人意想不到的是,2177 年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须在最短的时间内迁往月球。
现有 n 个太空站位于地球与月球之间,且有 m 艘公共交通太空船在其间来回穿梭。每个太空站可容纳无限多的人,而每艘太空船 i 只可容纳 H[i]个人。每艘太空船将周期性地停靠一系列的太空站,例如:(1,3,4)表示该太空船将周期性地停靠太空站 134134134…。每一艘太空船从一个太空站驶往任一太空站耗时均为 1。人们只能在太空船停靠太空站(或月球、地球)时上、下船。
初始时所有人全在地球上,太空船全在初始站。试设计一个算法,找出让所有人尽快地全部转移到月球上的运输方案。
对于给定的太空船的信息,找到让所有人尽快地全部转移到月球上的运输方案。
输入输出格式
输入格式:
第 1 行有 3 个正整数 n(太空站个数),m(太空船个数)和 k(需要运送的地球上的人的个数)。其中 n<=13 m<=20, 1<=k<=50。
接下来的 m 行给出太空船的信息。第 i+1 行说明太空船 pi。第 1 个数表示 pi 可容纳的人数 Hpi;第 2 个数表示 pi 一个周期停靠的太空站个数 r,1<=r<=n+2;随后 r 个数是停靠的太空站的编号(Si1,Si2,…,Sir),地球用 0 表示,月球用-1 表示。
时刻 0 时,所有太空船都在初始站,然后开始运行。在时刻 1,2,3…等正点时刻各艘太空船停靠相应的太空站。人只有在 0,1,2…等正点时刻才能上下太空船。
输出格式:
程序运行结束时,将全部人员安全转移所需的时间输出。如果问题
无解,则输出 0。
解题思路:
假如说告诉你多少天,问转移人口,那是不是会好一些,
按时间分层,不同层相同点间按照时间方向建$inf$的边,
跑一边最大流,源点是0时刻的地球,汇点是T时刻的月球。
最大流就是人口。
所以枚举判断好了。
代码:
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
const int oo=0x3f3f3f3f;
struct pnt{
int hd;
int lyr;
int now;
}p[];
struct ent{
int twd;
int lst;
int vls;
}e[];
int cnt;
int n,m,k;
int s,t;
int size;
int H[];
int fa[];
std::queue<int>Q;
std::vector<int>st[];
void ade(int f,int t,int v)
{
cnt++;
e[cnt].twd=t;
e[cnt].vls=v;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
bool Bfs(void)
{
while(!Q.empty())
Q.pop();
for(int i=;i<=size;i++)
p[i].lyr=;
p[s].lyr=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front();
Q.pop();
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].lyr==&&e[i].vls>)
{
p[to].lyr=p[x].lyr+;
if(to==t)
return true;
Q.push(to);
}
}
}
return false;
}
int Dfs(int x,int fll)
{
if(x==t)
return fll;
for(int& i=p[x].now;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].lyr==p[x].lyr+&&e[i].vls>)
{
int ans=Dfs(to,std::min(fll,e[i].vls));
if(ans>)
{
e[i].vls-=ans;
e[((i-)^)+].vls+=ans;
return ans;
}
}
}
return ;
}
int Dinic(void)
{
int ans=;
while(Bfs())
{
for(int i=;i<=size;i++)
p[i].now=p[i].hd;
int dlt;
while(dlt=Dfs(s,oo))
ans+=dlt;
}
return ans;
}
int finf(int x)
{
return fa[x]==x?x:fa[x]=finf(fa[x]);
}
int main()
{
// freopen("a.in","r",stdin);
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n+m+;i++)fa[i]=i;
for(int i=;i<=m;i++)
{
scanf("%d",&H[i]);
int tmp;
scanf("%d",&tmp);
for(int j=;j<=tmp;j++)
{
int tl;
scanf("%d",&tl);
if(tl==)tl=n+;
if(tl==-)tl=n+;
st[i].push_back(tl);
int f1=finf(tl);
int f2=finf(n++i);
if(f1!=f2)
fa[f1]=f2;
}
}
if(finf(n+)!=finf(n+))
{
printf("%d\n",);
return ;
}
s=n+;
int N;
int popu=;
for(N=;;N++)
{
if(N)
{
for(int i=;i<=n+m+;i++)
{
ade((N-)*(n+m+)+i,N*(n+m+)+i,oo);
ade(N*(n+m+)+i,(N-)*(n+m+)+i,);
}
}
size=(N+)*(n+m+);
t=N*(n+m+)+n+;
for(int i=;i<=m;i++)
{
int tp=st[i][N%st[i].size()];
if(tp!=n+)
{
ade(N*(n+m+)+n++i,N*(n+m+)+tp,H[i]);
ade(N*(n+m+)+tp,N*(n+m+)+n++i,);
}
if(tp!=n+)
{
ade(N*(n+m+)+tp,N*(n+m+)+n++i,H[i]);
ade(N*(n+m+)+n++i,N*(n+m+)+tp,);
}
}
popu+=Dinic();
if(popu<k);else break;
}
printf("%d\n",N);
return ;
}
LuoguP2754 [CTSC1999]家园(分层图,最大流)的更多相关文章
- [CTSC1999]家园 分层图网络流_并查集
Code: #include<cstdio> #include<vector> #include<algorithm> #include<queue> ...
- ZOJ-2364 Data Transmission 分层图阻塞流 Dinic+贪心预流
题意:给定一个分层图,即只能够在相邻层次之间流动,给定了各个顶点的层次.要求输出一个阻塞流. 分析:该题直接Dinic求最大流TLE了,网上说采用Isap也TLE,而最大流中的最高标号预流推进(HLP ...
- 洛谷4400 BlueMary的旅行(分层图+最大流)
qwq 首先,我们观察到题目中提到的每天只能乘坐一次航班的限制,很容易想到建分层图,也就是通过枚举天数,然后每天加入一层新的点. (然而我一开始想的却是erf) 考虑从小到大枚举天数,然后每次新建一层 ...
- bzoj 1189: [HNOI2007]紧急疏散evacuate 分层图最大流_拆点_二分
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- YbtOJ-大收藏家【分层图,最大流】
正题 题目链接:https://www.ybtoj.com.cn/contest/117/problem/2 题目大意 \(n\)个人,每人有\(a_i\)个属于自己的物品.\(m\)次交换依次进行, ...
- 【洛谷 P2754】 [CTSC1999]家园(最大流)
题目链接 突然发现Dinic很好写诶.. 第一次数组开小了,玄学\(WA\),what?数据范围描述有误? 分层图,每天为一层. 把上一天的每个空间站向这一天连一条流量为inf的边,表示可以原地不动. ...
- 洛谷2754 [CTSC1999]家园
题目链接:[CTSC1999]家园 这个题目我们不是很好在做网络流的时候判断是否有解,因此我们考虑分开来做 对于是否有解的判断,我们唯一需要解决的是飞船的周期停泊问题,对于这个问题,我们可以用并查集解 ...
- ACdream 1017 [分层图][网络流]
/* 大连热身C题 不要低头,不要放弃,不要气馁,不要慌张 题意: 给一个城市路线图,给定起点给定终点.有n个货物从起点运送到终点.城市的边是无向边. 每个货物每天如果通过某条路,那么这天这条路只能运 ...
- [网络流24题][CTSC1999] 家园
题目链接:戳我 对于这种一个点(表面意义上的一个点,比如说一个位置)对应多种情况的(比如说随着时间的推移有着不同的状态,而且这种状态>2),我们考虑在类似于分层图上面跑网络流. 比如说这道题,周 ...
随机推荐
- Signal programming
Signal programming is used in the same sense as dataflow programming, and is similar to event-driven ...
- Xrdp - 通过Windows的RDP连接Linux远程桌面(Ubuntu/CentOS/Redhat 7)(转载)
您多久访问一次Linux桌面? 您使用什么工具来访问远程桌面? Xrdp是一个开源工具,允许用户通过Windows RDP访问Linux远程桌面. 除了Windows RDP之外,xr ...
- NodeJS学习笔记 (10)网络TCP-net(ok)
模块概览 net模块是同样是nodejs的核心模块.在http模块概览里提到,http.Server继承了net.Server,此外,http客户端与http服务端的通信均依赖于socket(net. ...
- POJ-2142 The Balance 扩展欧几里德(+绝对值和最小化)
题目链接:https://cn.vjudge.net/problem/POJ-2142 题意 自己看题吧,懒得解释 思路 第一部分就是扩展欧几里德 接下来是根据 $ x=x_0+kb', y=y_0- ...
- bzoj2843极地旅行社题解
题目大意 有n座小岛,当中每一个岛都有若干帝企鹅. 一開始岛与岛之间互不相连.有m个操作.各自是在两个岛之间修一座双向桥,若两岛已连通则不修并输出no,若不连通就输出yes并修建.改动一个岛上帝企鹅的 ...
- 在kettle中实现数据验证和检查
在kettle中实现数据验证和检查 在ETL项目,输入数据通常不能保证一致性.在kettle中有一些步骤能够实现数据验证或检查.验证步骤能够在一些计算的基础上验证行货字段:过滤步骤实现数据过滤:jav ...
- 14.idea右键单击没有 svn选项处理办法
转自:http://www.cnblogs.com/xiohao/p/5044213.html 问题一: IntelliJ IDEA打开带SVN信息的项目不显示SVN信息,项目右键SVN以及图标还有C ...
- linux关于用户密码家目录总结
创建用户及其家目录useradd -d /home/tomcat -m tomcat接着修改密码passwd tomcat usermod -s /sbin/nologin + 用户名 禁止登录ssh ...
- Ubuntu16.04添加HP Laserjet Pro M128fn打印机和驱动
一.全部设置->打印机->添加新打印机 添加打印机 二.选择自动搜索到的网络打印机HP Laserjet Pro M128fn,点击添加. 三.添加打印机完成,打印测试页进行测试. 四. ...
- python jieba分词工具
源码地址:https://github.com/fxsjy/jieba 演示地址:http://jiebademo.ap01.aws.af.cm/ 特点 1,支持三种分词模式: a,精确模式,试图将句 ...