bzoj 2044三维导弹拦截 二分图匹配

来源:互联网 发布:慕课平台有哪些 知乎 编辑:程序博客网 时间:2024/06/06 14:01

题意:导弹拦截三维版,第一问求最多多少个,第二问求多少个系统能全部打掉。n<=1e3。
一看第一问以为自己穿越了,怎么tg就要cdq啊,一看n=1000= =随便做啊。
第二问最小路径覆盖随便搞,最小路径覆盖=最长反链,跟CTSC2008那题一样。
1A

#include <cstdio>  #include <iostream>  #include <algorithm>  #define N 1005  #define M 500505  using namespace std;  struct bom{int x,y,z;}s[N];  int b[N],lar,tot,nxt[M],point[M],v[M],belong[N],vis[N];  void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}  bool operator <(bom j,bom i){return (j.x<i.x&&j.y<i.y&&j.z<i.z);}  bool find(int x,int k)  {      for (int i=point[x];i;i=nxt[i])        if(vis[v[i]]!=k)        {          vis[v[i]]=k;          if (!belong[v[i]] || find(belong[v[i]],k)){belong[v[i]]=x;return true;}        }      return false;  }  int cmp(bom a,bom b){if (a.x==b.x) if (a.y==b.y) return a.z<b.z;else return a.y<b.y;else return a.x<b.x;}  int main()  {      freopen("missile.in","r",stdin);    freopen("missile.out","w",stdout);    int n,i,j;      scanf("%d",&n);      for (i=1;i<=n;i++) scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z);      sort(s+1,s+n+1,cmp);      for (i=1;i<=n;i++)      {          int maxx=0,mb;          for (j=1;j<=n;j++)            if (b[j]>maxx && s[j]<s[i])            {              maxx=b[j];              mb=j;            }          b[i]=maxx+1;          lar=max(lar,b[i]);      }      for (i=1;i<=n;i++)        for (j=1;j<=n;j++)          if (i!=j && s[i]<s[j])             addline(i,j);      printf("%d\n",lar);      int maxx=0;      for (i=1;i<=n;i++)        if (find(i,i)) maxx++;      printf("%d",n-maxx);  }  
原创粉丝点击