网络流,对三种武器分别有不同建图的方法,核心宗旨是:源点->武器->飞船->汇点。

  • SQL rockets – every SQL rocket can destroy at most one spaceship in the given set.
  • Cognition beams – every Cognition beam has an interval [l,r],and can destroy at most one spaceship in that interval.
  • OMG bazooka – every OMG bazooka has three possible targets, however, each bazooka can destroy either zero or exactly two spaceships. In addition, due to the smart targeting system, the sets of the three possible targets of any two different OMG bazookas are disjoint (that means that every ship is targeted with at most one OMG bazooka).

因为题目种对三种武器做了如下规定:

1.SQL rockets:ΣK <=100000,可以直接建图。

2.[l,r]中挑一个毁灭,则可以用线段树建图。

3.所有的OMG bazooka能销毁的目标集合之间互不相交,只能摧毁两个或者不摧毁。则由贪心策略得到摧毁最多舰船时所有的bazooka一定会被使用。

证明:假设最优状态下有一枚bazooka x无法使用;则x所能摧毁的集合中有两个或者三个被别的武器所摧毁,一共消耗了两个或者三个;在使用x后,有武器多余出来被用来摧毁别的目标,则不使用x的最优状态不是最优状态(没有未来的未来不是我想要的未来);

确定使用贪心后,就先把bazooka消灭的武器数量添加上,在这个节点稍微操作一下就好;

仔(can)细(kao)思(ti)考(jie)后,得到了如下的代码:

#include<bits/stdc++.h>
#define N 200005
#define inf 0x3f3f3f3f
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mid ((l+r)>>1)
typedef unsigned int __Index;
__Index tot;
__Index id[N],Begin;
int cnt,head[N],cur_edge[N],pre[N];
bool vis[N];
struct Edge{int v,cap,next;
}edge[N];
inline void __add(__Index a,__Index b,int c){edge[++cnt].v = b;edge[cnt].cap = c;edge[cnt].next = head[a];head[a] = cnt;
}
void add(__Index a,__Index b,int c){__add(a,b,c);__add(b,a,0);
}
void build(__Index l,__Index r,__Index rt){id[rt]=++tot;if(l==r){add(id[rt],l,1);return;}build(l,mid,lson);build(mid+1,r,rson);add(id[rt],id[lson],inf);add(id[rt],id[rson],inf);
}
void upDate(__Index L,__Index R,__Index l,__Index r,__Index rt) {if (L <= l and r <= R) {add(tot, id[rt], 1);return;}if (R <= mid)upDate(L, R, l, mid, lson);else if (L > mid)upDate(L, R, mid + 1, r, rson);else {upDate(L, mid, l, mid, lson);upDate(mid+1,R,mid+1,r,rson);}
}
__Index _n,m,src,dst,n;
int d[N],numd[N];
using namespace std;
void Bfs(int sink){memset(numd,0,sizeof(numd));fill(d+1,d+1+n,n);numd[n] = n;d[sink] = 0;--numd[n],++numd[0];queue<int>Q;Q.push(sink);while(!Q.empty()){int v = Q.front();Q.pop();for(int i = head[v] ,u; ~i ; i = edge[i].next){u = edge[i].v;if(d[u] < n )continue;d[u] = d[v]+1;--numd[n];++numd[d[u]];Q.push(u);}}
}
int SAP(__Index source,__Index sink){memcpy(cur_edge,head,(n+1)*sizeof(int));int max_flow = 0;Bfs(sink);int u = source,neck = 0;while (d[source] < n){if(u==sink){int cur_flow = inf;for(int from = source ; from!=sink;from = edge[cur_edge[from]].v){if(cur_flow>edge[cur_edge[from]].cap){neck = (__Index)from;cur_flow = edge[cur_edge[from]].cap;}}for(int from=source; from!=sink; from=edge[cur_edge[from]].v){int tmp=cur_edge[from];edge[tmp].cap-=cur_flow;edge[tmp^1].cap+=cur_flow;}max_flow+=cur_flow;//累加计算最大流u=neck;}int i;for(i = cur_edge[u] ; ~i ; i = edge[i].next){if(edge[i].cap and d[u] == d[edge[i].v]+1)break;}if(-1!=i){cur_edge[u] = i;pre[edge[i].v] = u;u = edge[i].v;}else{--numd[d[u]];if(!numd[d[u]])break;cur_edge[u] = head[u];int tmp = n;for(int j = head[u] ; ~j ; j = edge[j].next){if(edge[j].cap and tmp > d[edge[j].v]){tmp = d[edge[j].v];}}d[u] = tmp+1;numd[d[u]]++;if(u!=source)u = pre[u];}}return max_flow;
}void init(){memset(head,-1, sizeof(head));tot = m;cnt = -1;src = ++tot;build(1,m,1);Begin = tot;
}
int tmp = 0;
map<int,int>mp[N];
void Query(int p){if( p > Begin){tmp = p-Begin;return;}auto it = mp[p].begin();Query(it->first);--it->second;if(!it->second)mp[p].erase(it);
}
int main(){ios::sync_with_stdio(false);cin>>_n>>m;init();int k,op,ans = 0;__Index sp,l,r,c;for(int i = 0 ; i < _n ; ++i){++tot;cin>>op;switch (op){case 0:cin>>k;while (k--){cin>>sp;add(tot,sp,1);}add(src,tot,1);break;case 1:cin>>l>>r;upDate(l,r,1,m,1);add(src,tot,1);break;default:cin>>l>>r>>c;add(tot,l,0);edge[cnt].cap = 1;add(tot,r,0);edge[cnt].cap = 1;add(tot,c,1);vis[l] = vis[r] = true;ans+=2;break;}}dst = ++tot;for(__Index i = 1 ; i <= m ; ++i){if(!vis[i])add(i,dst,1);}n = tot;ans+=SAP(src,dst);for(int i=1;i<=tot;++i){for(int j = head[i] ; ~j  ; j = edge[j].next){if((j&1)and edge[j].cap){mp[i][edge[j].v] = edge[j].cap;}}}cout<<ans<<"\n";for(int i = 1 ; i <=  m ; ++i){bool f = true;for(int j = head[i] ; (~j) and f ; j = edge[j].next){if(edge[j].v == dst and edge[j].cap==1)f = false;}if(f){Query(i);cout<<tmp<<" "<<i<<"\n";}}
}

转载于:https://www.cnblogs.com/DevilInChina/p/9856219.html

CodeForces 1045A. Last chance(线段树+网络流SAP)相关推荐

  1. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  2. Codeforces 997E Good Subsegments (线段树)

    题目链接 https://codeforces.com/contest/997/problem/E 题解 经典题,鸽了 159 天终于看明白题解了.. 考虑一个区间是连续的等价于这个区间内的 \((\ ...

  3. CodeForces - 1539F Strange Array(线段树区间合并)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,规定位置 iii 的贡献是:设 x=a[i]x=a[i]x=a[i],选择一个包含 iii 的区间 [l,r][l,r][l,r],将其中 ...

  4. CodeForces - 1430E String Reversal(线段树+模拟)

    题目链接:点击查看 题目大意:给出一个字符串 sss ,令其反转的串为 ttt ,每次操作可以将 ttt 中的两个相邻位置的字符交换,问最少需要进行多少次操作才能使得 ttt 变成 sss 题目分析: ...

  5. 【codeforces 12D】【线段树】【降维】【离散化】【三元组比较大小】

    [题意] 给出n个女士的三位属性xi,yi,zi(注意此处是一行x给完再给y再给z).若存在xi>xj && yi > yj  && zi>zj ,那 ...

  6. Codeforces 1108 E2(线段树+思维)

    传送们 题意: 给你一个长度为nnn的数列bbb.以及mmm个区间. 你可以选取111个或多个这样的区间aia_iai​,使得令区间aia_iai​所对应的所有值bib_ibi​都减111.你最终要使 ...

  7. CodeForces - 817F MEX Queries(线段树lazy序)

    题目链接:点击查看 题目大意:初始时有一个空的集合,需要执行 n 次操作: 1 l r:将区间 [ l , r ] 内未出现的数加入到集合中 2 l r:将区间 [ l , r ] 内出现的数字全部删 ...

  8. CodeForces - 1454F Array Partition(线段树+二分)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在要求求出任意一组 x , y , z,满足下列条件: x + y + z = n max( 1 , x ) = min( x + 1 , ...

  9. CodeForces - 1440E Greedy Shopping(线段树)

    题目链接:点击查看 题目大意:给出一个非严格递减的子序列,需要完成 m 次操作,分为下列两种类型: 1 x y:将区间 [ 1 , x ] 中的数进行 a[ i ] = max( a[ i ] , y ...

最新文章

  1. linux自带的cd刻录,linux下刻录CDROM的命令
  2. Redis的安装部署
  3. rabbitmq的基本使用
  4. c语言 int top,顺序栈(C语言,静态栈)
  5. linux学习笔记(五):开机、关机、开机日志
  6. 百度地图API : 自定义标注图标
  7. Linux shell 脚本中”21″的含义解释
  8. mysql lvs+keepalived+mha_MHA+Lvs+Keepalived实现MySQL的高可用及读负载均衡_2(MySQL)
  9. SPSS安装以及如何解决can not create java virtual machine问题
  10. Unity官网地址变更为https://unity.cn/
  11. oracle 建表id自增长_oracle建表设置主键自增
  12. “四通一达”本一家,这家人是如何“承包”中国快递半壁江山的?
  13. IDL---批量波段合成(只要点击运行,自动化处理,解放生产力)
  14. snipeit 安装、备份文件恢复
  15. 【阅读笔记】Towards Personalized Federated Learning个性化联邦综述
  16. 阿里云服务器上搭建宝塔
  17. 一些电商英文缩写的解释
  18. 移动端测试——移动端基础
  19. 如何计算机械费里有多少电费,企业用电的电费是如何计算
  20. PS高阶操作之木质纹理

热门文章

  1. 集合(set) 深浅拷贝
  2. 幼儿园计算机培训心得,幼儿教师培训心得体会
  3. 【网络取证篇】suy网络工具包
  4. 爱奇艺播放技术——300ms背后的故事
  5. 怎么关闭惠普暗影精灵OMEN 8的主机灯
  6. python编程从入门到实践练习15-3:分子运动
  7. 牵丝戏计算机谱,急求牵丝戏计算器谱完整版!!!
  8. Python语法易混淆
  9. creo中公制单位的设定问题(永久设定)
  10. python ccf题解 201409-1 相邻数对