题目链接:戳我

对于这种一个点(表面意义上的一个点,比如说一个位置)对应多种情况的(比如说随着时间的推移有着不同的状态,而且这种状态>2),我们考虑在类似于分层图上面跑网络流。

比如说这道题,周期的暴力处理显然是一件很棘手的事情,我们看到数据范围这么小,就可以想一想把每个时间点的图都建出来——

每个点对应哪一个空间站在第几个单位时间的状态,然后把地球和月球也拆成在该单位时间时的状态。

对于无解的情况,只需要并查集维护,如果不存在有从地球到月亮的路径就是无解了。有解的情况,我们依次枚举答案,在建图之后跑最大流,如果此时最大流大于需要运送的人数,那么显然就可以了。

怎么建图呢?

首先地球是起始站,源点肯定要向每个时刻的地球连边吧,容量INF。然后月球是终点,所以要向每个时刻的月球连边,容量INF。之后对于在空间站的人们就是两种情况——1、人们可以选择此时在该空间站的飞船,飞向下一个空间站(/地球/月球)。2、无法移动,所以留在此处。显然我们把时刻拆开之后,很轻易就能计算出对于每个飞船,当前时刻的位置和下一时刻的位置,直接在分层图上连边即可,容量为最大载重。因为人有可能无法移动,而且空间站的容量为无限大,所以对于每个空间站,要向下一个时刻连一条边,容量INF。

最后一点,此题与一般的网络流题问你决策最优化有所不同,是问你一个数量需要在什么情况下才小于等于最大流,注意可以用枚举答案来变成判定性问题呢(和二分的思路有点像?其实应该也可以直接二分答案,然后不断地建立新图跑看是否可行。但是因为是dinic算法啦,一个一个枚举答案然后在残图上面继续拓展就不需要建立新图了。qwqwq)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#define MAXN 100010
#define MAXM 1010
#define S 0
#define T 10001
using namespace std;
int n,m,k,t=1,ans,all,sum;
int to[MAXM][MAXM],num[MAXN],cap[MAXN],head[MAXN],dis[MAXN],cur[MAXN],fa[MAXN];
vector<int>v[MAXM];
struct Edge{int nxt,to,dis;}edge[MAXN<<1];
inline void add(int from,int to,int dis)
{
edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void uni(int x,int y)
{
int a=find(x),b=find(y);
if(a!=b) fa[a]=b;
}
inline bool bfs()
{
queue<int>q;
memset(dis,0x3f,sizeof(dis));
memcpy(cur,head,sizeof(head));
q.push(S);dis[S]=0;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(dis[v]==0x3f3f3f3f&&edge[i].dis)
dis[v]=dis[u]+1,q.push(v);
}
}
if(dis[T]==0x3f3f3f3f) return false;
return true;
} inline int dfs(int x,int f)
{
if(!f||x==T) return f;
int used=0,w;
for(int i=cur[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
cur[x]=i;
if(dis[v]==dis[x]+1&&(w=dfs(v,min(f,edge[i].dis))))
{
edge[i].dis-=w,edge[i^1].dis+=w;
used+=w,f-=w;
if(!f) break;
}
}
return used;
}
inline int dinic()
{
int cur_ans=0;
while(bfs()) cur_ans+=dfs(S,2147483647);
return cur_ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n+2;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&cap[i],&num[i]);
for(int j=1;j<=num[i];j++)
{
int p;
scanf("%d",&p);
if(p==-1) p=n+2;
else if(p==0) p=n+1;
v[i].push_back(p);
if(j!=1) uni(p,v[i][v[i].size()-2]);
}
}
if(find(n+1)!=find(n+2)){printf("0\n");return 0;}
all=n+2;
add(S,all-1,2147483647);
add(all,T,2147483647);
for(ans=1;;ans++)
{
for(int i=1;i<=m;i++)
{
int now=v[i][ans%num[i]];
int pre=v[i][(ans-1+num[i])%num[i]];
add(all*(ans-1)+pre,all*ans+now,cap[i]);
}
add(S,all*ans+all-1,2147483647);
add(ans*all+all,T,2147483647);
for(int j=1;j<=n;j++)
add((ans-1)*all+j,ans*all+j,2147483647);
sum+=dinic();
if(sum>=k){printf("%d\n",ans);break;}
}
return 0;
}

[网络流24题][CTSC1999] 家园的更多相关文章

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

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

  2. COGS743. [网络流24题] 最长k可重区间集

    743. [网络流24题] 最长k可重区间集 ★★★   输入文件:interv.in   输出文件:interv.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述: «编 ...

  3. Cogs 14. [网络流24题] 搭配飞行员

    这道题其实蛮好想的,因为分为正,副飞行员.所以就把正飞行员当作Boy,副飞行员当作Girl.然后做Hungry即可. #include<bits/stdc++.h> using names ...

  4. 【线性规划与网络流 24题】已完成(3道题因为某些奇怪的原因被抛弃了QAQ)

    写在前面:SDOI2016 Round1滚粗后蒟蒻开始做网络流来自我拯救(2016-04-11再过几天就要考先修课,现在做网络流24题貌似没什么用←退役节奏) 做的题目将附上日期,见证我龟速刷题. 1 ...

  5. cogs_14_搭配飞行员_(二分图匹配+最大流,网络流24题#01)

    描述 http://cojs.tk/cogs/problem/problem.php?pid=14 有一些正飞行员和副飞行员,给出每个正飞行员可以和哪些副飞行员一起飞.一架飞机上必须一正一副,求最多多 ...

  6. BZOJ_1221_ [HNOI2001]_软件开发(最小费用流,网络流24题#10)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1221 n天,每天需要r个毛巾,用完以后可以洗,要么花fa洗a天,要么花fb洗b天,毛巾不够了可 ...

  7. 【网络流24题】 No.12 软件补丁问题(最小转移代价 最短路)

    [题意] T 公司发现其研制的一个软件中有 n 个错误, 随即为该软件发放了一批共 m 个补丁程序. 每一个补丁程序都有其特定的适用环境, 某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才 ...

  8. 【网络流24题】No.1 搭配飞行员(飞行员配对方案问题)

    [问题描述]     飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞 ...

  9. CJOJ 1494 【网络流24题】 搭配飞行员(二分图最大匹配)

    CJOJ 1494 [网络流24题] 搭配飞行员(二分图最大匹配) Description 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾 ...

随机推荐

  1. 将maven打包为一个jar(可以体外加入jar)

    使用 maven-compiler-plugin插件, 在maven的pom的<build></build>标签中上加入 <build> <plugins&g ...

  2. Python与Go冒泡排序

    #!/usr/bin/env python # -*- coding: utf-8 -*- # 冒泡排序法 def bubbling(array): # 时间复杂度:O(n^2) for i in r ...

  3. linux:alias

    linux系统下常用一个“命令”ll,它实质上是一个别名,而非命令. 我们用它的前提是,在~/.bashrc文件里打开,默认有条记录: #alias ll=’ls -l’ 这就是别名的格式.把注释去掉 ...

  4. hibernate初使用

    准备工作,安装及配置Hibernate http://zhoualine.iteye.com/blog/1190141 在产生数据库表映射 Java 对象时,我增加了数据库中的两张表分别为Chatlo ...

  5. SQL 中怎么查询数据库中具有的表、存储过程、试图数目、总触发器数、作业数

    用户表:select count(*) 总表数 from sysobjects where xtype='u' 刚才那个是用户表,下面这个是系统表加用户表: select count(*) 总表数 f ...

  6. oo原则

    基本原则: 封装变化Encapsulate what varies. 面向接口编程而非实现 Code to an interface rather than to an implementation. ...

  7. Java中String类型详解

    这篇博客是我一直想总结的,这两天一直比较忙,先上传下照片吧,过后有时间再弄成正常的. 本文主要是对Java中String类型的总结,包括其在JVM中是怎么存储的...

  8. toFixed

    1,toFixed要使用与Number数据类型 2.parseInt将字符串转换为整形 3.parseFloat将字符串转换为浮点型

  9. 封装request.get_params批量取值

    @json_request_validator(post_schema) 装饰器 from functools import wraps from schema import SchemaError ...

  10. wsl命令行

    参考: https://docs.microsoft.com/en-us/windows/wsl/about 查看已安装 wslconfig /l /all 重装 wslconfig /u debia ...