bzoj 2044 三维导弹拦截——DAG最小路径覆盖(二分图)

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2044

还以为是CDQ。发现自己不会三维以上的……

第一问可以n^2。然后是求最长不下降子序列吗?dilworth好像不能用吧。

那就是能从自己转移到哪些状态就从自己向哪些状态连边,然后就是最小路径覆盖了。用二分图的 n-最大匹配 。

注意:没有位置的限制所以可以先按 x 排序!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1005,M=N*N;
int n,hd[N<<1],xnt,to[M],nxt[M],dp[N],ans,per[N];
bool vis[N];
struct Node{
    int x,y,z;
    bool operator< (const Node &b) const
    {return x<b.x;}
}a[N];
struct Ed{
    int x,y;Ed(int x=0,int y=0):x(x),y(y) {}
}ed[M];
void add(int x,int y)
{
    to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;
}
bool dfs(int cr)
{
    for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]])
    {
        vis[v]=1;
        if(!per[v]||dfs(per[v]))
        {
            per[v]=cr;return true;
        }
    }
    return false;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    {
        dp[i]=1;
        for(int j=1;j<i;j++)
            if(a[j].x<a[i].x&&a[j].y<a[i].y&&a[j].z<a[i].z)
                dp[i]=max(dp[i],dp[j]+1),ed[++xnt]=Ed(j,i);
        ans=max(ans,dp[i]);
    }
    printf("%d\n",ans);  ans=0;

    int tmp=xnt;  xnt=0;
    for(int i=1;i<=tmp;i++) add(ed[i].x,ed[i].y);
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof vis);
        ans+=dfs(i);
    }
    printf("%d\n",n-ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/9534851.html

时间: 2024-12-08 22:51:42

bzoj 2044 三维导弹拦截——DAG最小路径覆盖(二分图)的相关文章

bzoj 2044 三维导弹拦截 —— 最小路径覆盖

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2044 第一问暴力 n^2 即可: 注意这道题对位置没要求!所以先按第一维排序一下即可: 然后拆入点和出点,求一个最小路径覆盖即可. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const

SSL 2732_导弹拦截_dp+最小路径覆盖

题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统. 敌国的导弹形成了立体打击,每个导弹可以抽象成一个三维空间中的点(x; y; z).拦截系统发射的炮弹也很好地应对了这种情况,每一发炮弹也可以视为一个三维空间中的点. 但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达三维空间中任意的点,但是以后每一发炮弹到达点的坐标(x; y; z) 的三个坐标值都必须大于前一发炮弹的对应坐标值. 某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所

uva1201 DAG 最小路径覆盖,转化为 二分图

大白例题P356 你在一座城市里负责一个大型活动的接待工作.你需要去送m个人从出发地到目的地,已知每个人的出发时间出发地点,和目的地点,你的任务是用尽量少的出租车送他们,使得每次出租车接客人,至少能提前一分钟达到他所在的位置,城市为网格 (x1,y1) ===>(x2,y2) 需要|x1-x2|+|y1-y2|分钟 题解: 本题的模型是DAG的最小路径覆盖.所谓最小路径覆盖就是在图中找尽量少的路径,使得每个结点恰好在一条路径上(话句话说,不同路径不能有公共点).单独的节点也可以作为一条路径. 本

POJ 1422 DAG最小路径覆盖

求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边即可. 故最小覆盖数还是 顶点数-最大匹配数 根据DAG建图的时候,就是DAG有边就给对应的端点建边 #include <iostream> #include <cstdio> #include <cstring> using namespace std; int d[15

【LA3126 训练指南】出租车 【DAG最小路径覆盖】

题意 你在一座城市里负责一个大型活动的接待工作.明天将有m位客人从城市的不同的位置出发,到达他们各自的目的地.已知每个人的出发时间,出发地点和目的地.你的任务是用尽量少的出租车送他们,使得每次出租车接客人时,至少能提前一分钟到达他所在的位置.注意,为了满足这一条件,要么这位客人是这辆出租车接送的第一个人,要么在接送完上一个客人后,有足够的时间从上一个目的地开到这里. 为了简单起见,假定城区是网格型的,地址用坐标(x,y)表示,出租车从(x1,y1)到(x2,y2)处需要行驶|x1-x2|+|y1

训练指南 UVALive - 3126(DAG最小路径覆盖)

layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 图论 - 训练指南 - 最小路径覆盖 Taxi Cab Scheme UVALive - 3126 题目大意:n个客人,从城市的不同位置出发,到达他们的目的地.已知每个人的出发时间hh:mm,出发地点(x1,y1)及目的地(x2,y2),要求使用最少的出租车接

POWOJ 1739: 魔术球问题 DAG最小路径覆盖转最大流

1739: 魔术球问题 题意: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.对于给定的n,计算在n根柱子上最多能放多少个球. tags: 对大佬来说应该是很素的一道题,但某还是花了好多时间才做出来.. 一开始连建图都有点懵,然后最小路径还是新概念,最大匹配也不太懂,最大流倒是会一点. 然后要打印答案,也不

POJ1422 Air Raid 【DAG最小路径覆盖】

Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6763   Accepted: 4034 Description Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an i

BZOJ 2150 部落战争 最小路径覆盖 二分图最大匹配

题目大意:给出一张地图,一个军队要征战整个土地.一块土地只能经过一次,有X的地方不能走,军队只会走R*C个格子,只会向下走,问最少需要多少军队能够征战所有的土地. 思路:这个是前几天考试的题,今天居然发现时BZ的原题,还好当时A掉了... 看到每个土地只能经过一次就想到了网络流什么的,再一想想好像是最小路径覆盖啊,然后拆点,建图,Hungary,二分图最小路径覆盖=点数-最大匹配,没了.. CODE: #include <cstdio> #include <cstring> #in