Problem Link

你在打怪。你有一个 \(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的更多相关文章

  1. 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)

    Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...

  2. 【uva 11082】Matrix Decompressing(图论--网络流最大流 Dinic+拆点二分图匹配)

    题意:有一个N行M列的正整数矩阵,输入N个前1~N行所有元素之和,以及M个前1~M列所有元素之和.要求找一个满足这些条件,并且矩阵中的元素都是1~20之间的正整数的矩阵.输入保证有解,而且1≤N,M≤ ...

  3. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  4. 图论--网络流--最大流 洛谷P4722(hlpp)

    题目描述 给定 nn 个点,mm 条有向边,给定每条边的容量,求从点 ss 到点 tt 的最大流. 输入格式 第一行包含四个正整数nn.mm.ss.tt,用空格分隔,分别表示点的个数.有向边的个数.源 ...

  5. 图论--网络流--费用流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 ...

  6. 图论--网络流--费用流--POJ 2156 Minimum Cost

    Description Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his s ...

  7. 图论--网络流--最大流 HDU 2883 kebab(离散化)

    Problem Description Almost everyone likes kebabs nowadays (Here a kebab means pieces of meat grilled ...

  8. 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)

    Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...

  9. 图论--网络流--最大流 HDU 3572 Task Schedule(限流建图,超级源汇)

    Problem Description Our geometry princess XMM has stoped her study in computational geometry to conc ...

  10. 图论--网络流--最大流--POJ 1698 Alice's Chance

    Description Alice, a charming girl, have been dreaming of being a movie star for long. Her chances w ...

随机推荐

  1. 火山引擎DataLeap数据血缘技术建设实践

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 DataLeap是火山引擎数智平台VeDI旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理 ...

  2. Docker 启动失败 (code=exited, status=1/FAILURE)错误解决办法

    ob for docker.service failed because the control process exited with error code. See "systemctl ...

  3. Interceptor Handle 执行顺序

    preHandle 调用时间:Controller方法处理之前 执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行 若返回false,则中断执行,注意:不会 ...

  4. 使用 FHE 实现加密大语言模型

    近来,大语言模型 (LLM) 已被证明是提高编程.内容生成.文本分析.网络搜索及远程学习等诸多领域生产力的可靠工具. 大语言模型对用户隐私的影响 尽管 LLM 很有吸引力,但如何保护好 输入给这些模型 ...

  5. 什么?你居然没有鸭鸭邮箱?@duck.com邮箱注册与使用

    @duck.com 是由专注于隐私的搜索引擎DuckDuckGo提供的面向所有人的匿名邮箱. 注册者可以设置一个自定义前缀,比如 one@duck.com,接着设置接收邮箱(如pete@gmail.c ...

  6. HDU-3032--Nim or not Nim?(博弈+SG打表)

    题目分析: 这是一个经典的Multi-SG游戏的问题. 相较于普通的Nim游戏,该游戏仅仅是多了拆成两堆这样的一个状态.即多了一个SG(x+y)的过程. 而根据SG定理,SG(x+y)这个游戏的结果可 ...

  7. 第六届蓝桥杯C++C组 A~F题题解

    蓝桥杯历年国赛真题汇总:Here 1. 分机号 X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位.比如: 751,520,321 都满足要求,而, ...

  8. C语言哈希表uthash的使用方法详解(附下载链接)

    uthash简介   由于C语言本身不存在哈希,但是当需要使用哈希表的时候自己构建哈希会异常复杂.因此,我们可以调用开源的第三方头文件,这只是一个头文件:uthash.h.我们需要做的就是将头文件复制 ...

  9. vue 基于axios封装request接口请求——request.js文件

    https://blog.csdn.net/m0_67393593/article/details/123266577?utm_medium=distribute.pc_relevant.none-t ...

  10. map三层循环遍历,操作数据

    let tempArr = this.oldCityList.map(item => { return { value: item.code, text: item.name, type: it ...