【图论,网络流】CF1525F Goblins And Gnomes
你在打怪。你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们所选的路径点不相交。如果某一波中所有点都被覆盖了,那你就输了。
你不能输。于是在第 \(i\) 波之前,你可以花费若干分钟备战,每分钟可以选一个点将它的入边或者出边全部删掉。给定 \(a_i,b_i\),如果你在第 \(i\) 分钟花了 \(x\) 分钟备战,则你在这一波的得分为 \(\max(0,a_i-b_ix)\)。
你想拿分。你的总得分为每一波的得分之和。在不输的前提下最大化这个总得分。输出方案。
\(n\le 500,m\le n(n-1)/2,k<n\)。
首先这个是最小不交链覆盖,直接拆点二分图,转化成二分图最大匹配。对于一张图,最小链覆盖的大小即为 \(n-\) 最大匹配大小。
然后考虑操作是什么,删去一个点的所有出边或所有入边?就是删掉二分图上的一个点!
问题变成了删点使得最大匹配减小。然后我们记起来一点,最大匹配 \(=\) 最小点覆盖!那么删掉最小点覆盖上一个点一定会使得最大匹配减小。因此一定有一种方案使得最大匹配减小。
怎么找到这个方案?考虑如果是左部点,合法的充要条件是删掉它之后不存在一条从 \(S\) 到它的匹配点的路径。然后又注意到一点,如果一个左部点合法,那么只有它的匹配点是指向它的,所以不存在 \(S\) 到它的匹配点的路径等价于不存在 \(S\) 到它的路径。于是我们就进行 \(n\) 轮 dfs,每轮 dfs 从 \(S\) 开始搜,找出一个 \(S\) 无法到达的左部点删掉(如果找不到就从 \(T\) 开始对称地搜,两者一定能找到其一)。找到要删的点之后记得把从它到 \(T\)(或从 \(S\) 到它)的流退掉。每删一个点只用花 \(O(n^2)\) 的时间遍历,这部分复杂度 \(O(n^3)\)。
然后得分是诈骗的。直接硬上一个 \(O(n^3)\) 的 dp 即可。前面这么麻烦是因为要输出方案。
总时间复杂度 \(O(n^3)\)。
点击查看代码
#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rev(i,a,b) for(int i=a;i>=b;i--)
#define Fin(file) freopen(file,"r",stdin);
#define Fout(file) freopen(file,"w",stdout);
using namespace std;
const int N=505,M=N*N; using ll = long long;
int n,m,S,T,K,head[N],nxt[M],to[M],dir[M],tot,vis[N],st[N],tp,lis[N],lcnt,num[N],g[N][N]; ll f[N][N];
bool dfs(int u,int o,function<bool(int)> Done){
vis[u]=1; if(Done(u)) return true;
for(int e=head[u];e;e=nxt[e]) if(dir[e]==o&&!vis[to[e]]){
st[++tp]=e; if(dfs(to[e],o,Done)) return true; else tp--;
}
return false;
}
void add(int x,int y){
nxt[++tot]=head[x]; head[x]=tot; to[tot]=y; dir[tot]=1;
nxt[++tot]=head[y]; head[y]=tot; to[tot]=x; dir[tot]=0;
}
bool ck(ll& x,ll y) { return x<y?x=y,true:false; }
int main(){
cin>>n>>m>>K; tot=1;
For(i,1,m){
int x,y; cin>>x>>y; x=x*2-1; y=y*2; add(x,y);
}
S=n*2+1,T=n*2+2; int tt=n;
For(i,1,n*2) i&1?add(S,i):add(i,T);
while(true){
tp=0; For(i,1,T) vis[i]=0;
if(!dfs(S,1,[&](int u){return u==T;})) break;
tt--; Rev(i,tp,1) dir[st[i]]^=1,dir[st[i]^1]^=1;
}
int ww=tt;
while(tt<=K){
tp=0; For(i,1,T) if(vis[i]!=-1) vis[i]=0;
dfs(S,1,[&](int){return false;});
int o=0; for(int i=1;i<2*n;i+=2) if(!vis[i]) { o=i; break; }
if(o==0){
tp=0; For(i,1,T) if(vis[i]!=-1) vis[i]=0;; dfs(T,0,[&](int){return false;});
for(int i=2;i<=2*n;i+=2) if(!vis[i]) { o=i; break; }
}
assert(o); num[tt++]=o;
tp=0; For(i,1,T) if(vis[i]!=-1) vis[i]=0;
if(o&1) assert(dfs(T,1,[&](int u){return u==o;})); else assert(dfs(S,0,[&](int u){return u==o;}));
Rev(i,tp,1) dir[st[i]]^=1,dir[st[i]^1]^=1;
vis[o]=-1;
}
memset(f,0xaf,sizeof(f)); f[0][0]=0;
For(i,1,K){
ll x,y; cin>>x>>y;
For(j,0,n) For(k,max(j,max(0,i-ww+1)),n){
if(ck(f[i][k],f[i-1][j]+max(0ll,x-(k-j)*y))) g[i][k]=j;
}
}
ll ans=f[0][1]; int j=-1; For(i,0,n) if(ck(ans,f[K][i])) j=i;
vector<int> Ans;
Rev(i,K,1){
Ans.push_back(0); int k=g[i][j];
while(j>k) Ans.push_back(num[--tt]),j--;
}
reverse(Ans.begin(),Ans.end());
cout<<Ans.size()<<'\n';
for(int x:Ans){
if(x==0) cout<<x<<' ';
else if(x&1) cout<<(x+1)/2<<' ';
else cout<<-x/2<<' ';
}
cout<<'\n';
return 0;
}
【图论,网络流】CF1525F Goblins And Gnomes的更多相关文章
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
- 【uva 11082】Matrix Decompressing(图论--网络流最大流 Dinic+拆点二分图匹配)
题意:有一个N行M列的正整数矩阵,输入N个前1~N行所有元素之和,以及M个前1~M列所有元素之和.要求找一个满足这些条件,并且矩阵中的元素都是1~20之间的正整数的矩阵.输入保证有解,而且1≤N,M≤ ...
- 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸
410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:pvz.out 简单对比时间限制:2 s 内存限制:512 MB [问题描述] Plants vs ...
- 图论--网络流--最大流 洛谷P4722(hlpp)
题目描述 给定 nn 个点,mm 条有向边,给定每条边的容量,求从点 ss 到点 tt 的最大流. 输入格式 第一行包含四个正整数nn.mm.ss.tt,用空格分隔,分别表示点的个数.有向边的个数.源 ...
- 图论--网络流--费用流POJ 2195 Going Home
Description On a grid map there are n little men and n houses. In each unit time, every little man c ...
- 图论--网络流--费用流--POJ 2156 Minimum Cost
Description Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his s ...
- 图论--网络流--最大流 HDU 2883 kebab(离散化)
Problem Description Almost everyone likes kebabs nowadays (Here a kebab means pieces of meat grilled ...
- 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)
Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...
- 图论--网络流--最大流 HDU 3572 Task Schedule(限流建图,超级源汇)
Problem Description Our geometry princess XMM has stoped her study in computational geometry to conc ...
- 图论--网络流--最大流--POJ 1698 Alice's Chance
Description Alice, a charming girl, have been dreaming of being a movie star for long. Her chances w ...
随机推荐
- openGauss内核分析:SQL by pass & 经典执行器
摘要:执行引擎一般负责查询的执行,执行引擎在SQL执行栈中起到接收优化器生成的执行计划Plan.并对通过存储引擎提供的数据读写接口,实现对数据进行计算得到查询的结果集. 本文分享自华为云社区<o ...
- HOCON:nginx配置文件后缀conf是什么格式类型文件夹?intellij如何编辑
nginx的配置为*.conf ,这个conf是么子文件?之前确实不清楚. HOCON 简介HOCON(Human-Optimized Config Object Notation)是一个易于使用的配 ...
- 如何在iPhone设备中查看崩溃日志
如何在iPhone设备中查看崩溃日志 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么? 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分 ...
- 开发调试更便捷!火山引擎 DataLeap 提供 Notebook 交互式开发体验
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 Notebook 是一种支持 REPL 模式的开发环境. 所谓「REPL」,即「读取-求值-输出」循环:输入一段代 ...
- Axure 标记元件
快照:可以用来表示控件的截图功能 箭头:有了连线,基本很少用它 便签:相关于便利贴,写些说明.备注, 标记:标记好数字,对应数字的标记做解释说明
- 大数据 - DWD&DIM 业务数据
业务数据的变化,我们可以通过 FlinkCDC 采集到,但是 FlinkCDC 是把全部数据统一写入一个 Topic 中, 这些数据包括事实数据,也包含维度数据,这样显然不利于日后的数据处理,所以这个 ...
- 熔断、限流、降级 —— SpringCloud Alibaba Sentinel
Sentinel 简介 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流.流量整形.熔断降级.系统负载保护.热点防护等多个维度来帮助开发者保 ...
- 注册中心 —— SpringCloud Netflix Eureka
Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务 ...
- 如何在 Unity 游戏中集成 AI 语音识别?
简介 语音识别是一项将语音转换为文本的技术,想象一下它如何在游戏中发挥作用?发出命令操纵控制面板或者游戏角色.直接与 NPC 对话.提升交互性等等,都有可能.本文将介绍如何使用 Hugging Fac ...
- java中类的普通初始化块一定在静态初始化块后运行吗
大部分教程都会告诉我们静态初始化块和静态字段总是在初始化块和普通类字段前运行,事实上也确实如此,直到我看到下面这样的代码: public class Test { static Test test = ...