题意:有nnn个武器和mmm个飞船,武器有下面三种

  1. 从给定的集合SSS中击破一个。
  2. 在给定的区间[L,R][L,R][L,R]中击破一个。
  3. 对于给定的a,b,ca,b,ca,b,c,选择000个或222个击破。特殊地,每个飞船最多被该操作的a,b,ca,b,ca,b,c指定一次。

求最多能击破的飞船数量,并输出一种方案。

n,m≤5×103,∑∣S∣≤105n,m\leq 5\times10^3,\sum|S|\leq10^5n,m≤5×103,∑∣S∣≤105

网络流大杂烩

操作333似乎是个经典的不可做问题。但注意到指定的三个飞船不会重复,且只有333能选222个,可以贪心地把所有333都覆盖(也可以通过后面的建图理解为什么贪心是正确的)

1、31、31、3操作直接建,222操作建个线段树优化建图

具体而言,先整一棵线段树,树上的父结点向儿子连容量为 INF 的边,叶子结点表示飞船,向TTT连容量为111。另开nnn个点,表示武器,111操作流111的流量直接连,222操作拆成log⁡\loglog个区间连,333操作流222的流量先记下来最后连上去,这样333操作会最先增广,然后后面无论怎么增广流量都是222(这也是为什么贪心是对的)

方案可以从TTT往回dfs,走有流的边。因为已经有流了,所以往这条边走一定有合法方案,走到武器点的时候立刻返回,并顺便退掉111的流量。

谁能告诉我怎么算数组大小啊

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <queue>
#define MAXN 1000005
#define MAXM 10000005
using namespace std;
const int INF=0x7fffffff;
struct edge{int u,v,c;}e[MAXN];
int head[MAXN],cur[MAXN],nxt[MAXM],cnt=1;
void insert(int u,int v,int c)
{e[++cnt]=(edge){u,v,c};nxt[cnt]=head[u];head[u]=cnt;
}
void addnode(int u,int v,int c){insert(u,v,c),insert(v,u,0);}
int dis[MAXN],S,T;
bool bfs()
{queue<int> q;q.push(S);memset(dis,-1,(T+5)*sizeof(int));dis[S]=0;while (!q.empty()){int u=q.front();q.pop();for (int i=head[u];i;i=nxt[i])if (e[i].c&&dis[e[i].v]==-1){dis[e[i].v]=dis[u]+1;q.push(e[i].v);if (e[i].v==T) return true;}}return false;
}
int dfs(int u,int f)
{if (u==T||!f) return f;int used=0;for (int &i=cur[u];i;i=nxt[i])if (e[i].c&&dis[e[i].v]==dis[u]+1){int w=dfs(e[i].v,min(f,e[i].c));if (!w) continue;used+=w,f-=w;e[i].c-=w,e[i^1].c+=w;if (!f) break;}if (!used) dis[u]=-1;return used;
}
inline int dinic()
{int mflow=0;while (bfs()) memcpy(cur,head,(T+5)*sizeof(int)),mflow+=dfs(S,INF);return mflow;
}
int pos[MAXN],sop[MAXN],mx;
#define lc p<<1
#define rc p<<1|1
void build(int p,int l,int r)
{mx=max(mx,p);if (l==r) return (void)(pos[l]=p,sop[p]=l);int mid=(l+r)>>1;build(lc,l,mid);build(rc,mid+1,r);addnode(p,lc,INF),addnode(p,rc,INF);
}
void query(int p,int l,int r,int ql,int qr,int u)
{if (ql<=l&&r<=qr) return (void)addnode(u,p,1);if (qr<l||r<ql) return;int mid=(l+r)>>1;query(lc,l,mid,ql,qr,u),query(rc,mid+1,r,ql,qr,u);
}
int x[MAXN],a[MAXN],b[MAXN],c[MAXN],tot,n,m;
int ans[MAXN];
int find(int u,int f)
{if (mx+1<=u&&u<=mx+n) return u;for (int i=head[u];i;i=nxt[i])if (e[i].c&&e[i].v!=f){--e[i].c;++e[i^1].c;return find(e[i].v,u);}return 0;
}
int main()
{scanf("%d%d",&n,&m);build(1,1,m);S=mx+n+1,T=S+1;for (int i=1;i<=n;i++){int type;scanf("%d",&type);if (type==0){addnode(S,mx+i,1);int k;scanf("%d",&k);while (k--){int x;scanf("%d",&x);addnode(mx+i,pos[x],1);}}if (type==1){addnode(S,mx+i,1);int l,r;scanf("%d%d",&l,&r);query(1,1,m,l,r,mx+i);}if (type==2){++tot;x[tot]=i;scanf("%d%d%d",&a[tot],&b[tot],&c[tot]);}}for (int i=1;i<=tot;i++){addnode(S,mx+x[i],2);addnode(mx+x[i],pos[a[i]],1);addnode(mx+x[i],pos[b[i]],1);addnode(mx+x[i],pos[c[i]],1);}for (int i=1;i<=m;i++) addnode(pos[i],T,1);printf("%d\n",dinic());for (int i=head[T];i;i=nxt[i])if (e[i].c){int t=find(e[i].v,T);if (t) printf("%d %d\n",t-mx,sop[e[i].v]);}return 0;
}

【CF1045A】A Last chance【贪心】【线段树优化建图】【网络流构造方案】相关推荐

  1. Codeforces 786B Legacy (线段树优化建图)

    Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...

  2. 线段树优化建图详解——区间连边之技巧,吊打紫题之利器

    我们从一道例题开始. CF786B Description Solution 朴素解法: 暴力连边+最短路 对于每次连边操作,我们逐一连边,最后在图上跑一遍单源最短路径算法即可. 时间复杂度 O ( ...

  3. Gym - 102174G 神圣的 F2 连接着我们 (线段树优化建图 + 多源最短路)

    Description 小白非常喜欢玩 "县际争霸" 这款游戏,虽然他的技术并不容乐观."县际争霸" 的地图共有两个县,每个县里各有 n n n 个据点.同一个 ...

  4. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

  5. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  6. P6348 [PA2011]Journeys 线段树优化建图 区间连区间

    传送门 文章目录 题意: 思路: 题意: 每次连接[a,b][a,b][a,b]与[c,d][c,d][c,d]之间所有点,让后跑最短路. 思路: 比普通的优化建图能简单点,我们只需要加两个虚点之间边 ...

  7. CodeForces - 787D - Legacy(线段树优化建图+最短路)

    题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...

  8. P5025-[SNOI2017]炸弹【tarjan,线段树优化建图】

    正题 题目链接:https://www.luogu.com.cn/problem/P5025 题目大意 .nnn个炸弹,每个在xxx位置处,范围为rrr.定义fif_ifi​表示第iii个炸弹爆炸能连 ...

  9. CodeForces---787D:Legacy【线段树优化建图+最短路】

    题目: 戳这里啊~~~ 题意: 给你三种操作:(1)点到点建边:(2)点到区间建边:(3)区间到点建边:最后求起点到其他点的最短距离 分析: 最短距离无非建边跑Dijkstra即可,考虑如何对区间建边 ...

最新文章

  1. hdu 2552 三足鼎立 关于tan的数论
  2. centos7下安装maven
  3. 【NOIP2015模拟10.22】矩形
  4. Reporting Service 在文本框中换行的问题
  5. 关于虚拟机vmware三种网络模式
  6. Sangmado 公共基础类库
  7. Error running ‘transmission‘: Unable to open debugger port (127.0.0.1:52469): java.net.SocketExcepti
  8. linux编程创建文件,快速创建linux文件
  9. Atitit springboot helloword 最简化 attilax总结
  10. java 求集合真子集_干货 | 集合与函数概念知识点总结
  11. Cygwin安装教程【超详细】
  12. 试题 算法训练 调和数列问题---蓝桥杯
  13. 中国地质大学英语语音学习笔记(三):音节与单词变形(ed,es,ing,est,er,派生等)导致的音节数和读音变化
  14. org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not runn Hbase shell 无法执行命令
  15. 【经典算法】:银行金额大写转换
  16. 基于博客系统的访客日志记录
  17. 双馈风机DFIG并网(Matlab Simulink) 有详细说明
  18. 自我实现者共同的性格特征
  19. 计算机正确开关机教案ppt,信息技术计算机开关机的正确操作ppt课件.ppt
  20. github上几个Xposed调试插件及其他开源插件

热门文章

  1. 男厕改女厕能多敷衍......
  2. 当全家人一起看电影,播到羞羞镜头时......
  3. 数据挖掘算法之-关联规则挖掘(Association Rule)(购物篮分析)
  4. 三次握手和四次挥手图解_三次握手和四次挥手简单理解
  5. python3 2.00gb怎么去掉单位_最值得期待的Python 3.9的新功能
  6. unity重定向_unity3D游戏开发之动画混合与动画重定向
  7. android byte[] 转string 好多问号_#WIPI# Android使用HID设备
  8. 查看服务器物理内存大小,如何看服务器的物理内存大小
  9. win10必须禁用的服务_【亲测】Win10系统如何彻底禁止自动更新 亲测有效的Win10关闭自动更新方法...
  10. python 里什么时候缩进_python什么时候缩进