【图论,网络流】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 ...
随机推荐
- Gzip之后继者Brotli浅析之CDN厂商的智能压缩,服务器Brotli设置
"智能压缩"按照又拍云的说法是,同时支持 Gzip 和 Brotli 压缩算法.根据用于浏览器开启自动选择不同压缩方式. Gzip 压缩算法 Gzip 基于 DEFLATE 算法, ...
- Axure 母版与元件
需要重复使用的元件,建议创建成母版: 如果修改了母版,所有页面中的母版元件将会被同步修改 元件:添加后,所有的 Axure 都可以使用 母版:只适用当前的 Axure 原型 拖放行为: 任意位置:可以 ...
- System.out.printf 格式化输出
System.out.printf @Test public void printTest() throws Exception { String str = "安倍晋三已无生命体征!!&q ...
- SpringBoot Jar 包太大 瘦身 【初试】
SpringBoot Jar 包太大 瘦身,建议使用时,参考: SpringBoot Jar 包太大 瘦身 [终极版] 29M, 排除少量JAR包方式 打包,排除指定jar 包 <build&g ...
- Python 基于深度学习的 opencv 车牌识别系统,可以准确识别车牌号
大家好,我是程序员徐师兄,6 年大厂程序员经验,点击关注我 简介 毕业设计基于Opencv的车牌识别系统 车牌搜索识别找出某个车牌号 对比识别车牌系统 车牌数据库认证系统 车牌图文搜索系统 车牌数据库 ...
- JSP | JSP 动作详解
原作者为 RioTian@cnblogs, 本作品采用 CC 4.0 BY 进行许可,转载请注明出处. 本篇学习自:C语言中文网,部分内容转载仅供学习使用. \[QAQ \] JSP 动作利用 XML ...
- 实时渲染前沿研究:在浏览器上实现了Facebook提出的DLSS算法
大家好,我基于WebNN在浏览器上实现了2020年Facebook提出的Neural-Supersampling-for-Real-time-Rendering算法.它是一个用于实时渲染的神经网络超采 ...
- 3D编程模式:开篇
大家好~现在开始新的系列文章:3D编程模式系列 本系列会介绍从我的实际开发经验中抽象提炼出来的编程模式,大家可直接应用它们到3D引擎开发.编辑器开发等领域中 相关资料: 课程录像回放 代码和课程ppt ...
- 一次完整的HTTP服务过程
- 从头到尾创建一个vue项目