JZOJ5354. 【NOIP2017提高A组模拟9.9】导弹拦截
2017-09-09 15:41
513 查看
Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。敌国的导弹形成了立体打击,每个导弹可以抽象成一个三维空间中的点(x; y; z)。拦截系统发射的炮弹也很好地应对了这种情况,每一发炮弹也可以视为一个三维空间中的点。
但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达三维空间中任意的点,但是以后每一发炮弹到达点的坐标(x; y; z) 的三个坐标值都必须大于前一发炮弹的对应坐标值。
某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹飞来的坐标,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。注意: 所有导弹都是同时飞来的。
Input
第一行一个正整数n,表示敌国导弹数目。接下来n 行,每行三个非负整数xi,yi,zi,表示一个敌国导弹的三维坐标。
数据保证所有的导弹坐标互不相同。
Output
第一行一个整数,表示一套系统最多拦截的导弹数。第二行一个整数,表示拦截所有导弹最少配备的系统数。
Sample Input
40 0 0
1 1 0
1 1 1
2 2 2
Sample Output
32
Data Constraint
对于30% 的数据,n <=10对于100% 的数据,n <= 1000,x; y; z <= 10^6
题解
这题分为两个问题,对于第一个问,我们是可以很简单地求出答案。我们根据能否接着发射导弹来连边。
如果两个导弹i,j,在i发射之后还可以发射j
也就是说xi<xj and yi<yj and zi<zj
就由i向j连一条有向边。
这样连边之后就一定是DAG。
对于第二问,我们先假设每个导弹都要一个系统,
那么最开始的时候就有n个系统。
如果在一个导弹发射之后,还能发射下一个导弹,那么这样就可以节省一个系统。
在它发射完以后,可以找下一个接着发射,也就是它的边连着的那些点。
但是,某些导弹可能在发射完多个导弹之后都可以发射它,那么这样就是重复。
那样就是一个二分图匹配,设这个DAG的最大匹配是m,
那么答案就是n-m。
code
#include<queue> #include<cstdio> #include<iostream> #include<algorithm> #include <cstring> #include <string.h> #include <cmath> #include <math.h> #define ll long long #define N 2003 #define db double #define P putchar #define G getchar #define mo 1000000007 using namespace std; char ch; void read(int &n) { n=0; ch=G(); while((ch<'0' || ch>'9') && ch!='-')ch=G(); ll w=1; if(ch=='-')w=-1,ch=G(); while('0'<=ch && ch<='9')n=n*10+ch-'0',ch=G(); n*=w; } int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a<b?a:b;} void write(int x) { if(x>9) write(x/10); P(x%10+'0'); } struct node{ int x,y,z; }a ; int f ,n,ans,mx,x; int d ,q ,l,r,g ; int next[N*N],t[N*N],b ,tot; bool bz ; bool pd(int x,int y) { return a[x].x<a[y].x && a[x].y<a[y].y && a[x].z<a[y].z; } void ins(int x,int y) { next[++tot]=b[x]; t[tot]=y; b[x]=tot; d[y]++; } bool find(int x) { for(int i=b[x];i;i=next[i]) { if(bz[t[i]])continue; bz[t[i]]=1; if(g[t[i]]==0 || find(g[t[i]])) { g[t[i]]=x; return 1; } } return 0; } int main() { freopen("missile.in","r",stdin); freopen("missile.out","w",stdout); read(n);memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) { read(a[i].x);read(a[i].y);read(a[i].z); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(pd(i,j))ins(i,j); l=r=0; for(int i=1;i<=n;i++) if(d[i]==0)q[++r]=i,f[i]=1; ans=r; while(l<r) { x=q[++l]; for(int i=b[x];i;i=next[i]) { f[t[i]]=max(f[t[i]],f[x]+1),d[t[i]]--; if(d[t[i]]==0)q[++r]=t[i]; } mx=max(mx,f[x]); } write(mx),P('\n'); ans=n; memset(bz,0,sizeof(bz)); for(int i=1;i<=n;i++) { memset(bz,0,sizeof(bz)); ans-=find(i); } write(ans); }
相关文章推荐
- 导弹拦截 【NOIP2017提高A组模拟9.9】
- JZOJ 5354. 【NOIP2017提高A组模拟9.9】导弹拦截
- JZOJ 5353. 【NOIP2017提高A组模拟9.9】村通网
- JZOJ 5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven
- 【jzoj5289】【NOIP2017提高组A组模拟8.17】【偷笑】【数据结构】
- 【jzoj5306】【NOIP2017提高A组模拟8.18】【棋盘游戏】
- 【JZOJ5287】【NOIP2017提高A组模拟8.16】最短路
- JZOJ 5347. 【NOIP2017提高A组模拟9.5】遥远的金字塔
- JZOJ 4932. 【NOIP2017提高组模拟12.24】B
- JZOJ 5177. 【NOIP2017提高组模拟6.28】TRAVEL
- JZOJ 5186. 【NOIP2017提高组模拟6.30】tty's home
- [JZOJ5394]【NOIP2017提高A组模拟10.5】Ping
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology
- 【JZOJ 5395】【NOIP2017提高A组模拟10.6】Count
- JZOJ100042. 【NOIP2017提高A组模拟7.12】保留道路
- JZOJ 100041. 【NOIP2017提高A组模拟7.12】列车调度
- jzoj5330 【NOIP2017提高A组模拟8.22】密码
- 【JZOJ4921】【NOIP2017提高组模拟12.10】幻魔皇
- 【JZOJ 5394】【NOIP2017提高A组模拟10.5】Ping
- JZOJ 5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven