洛谷P2711 小行星

题目描述

星云中有n颗行星,每颗行星的位置是(x,y,z)。每次可以消除一个面(即x,y或z坐标相等)的行星,但是由于时间有限,求消除这些行星的最少次数。

输入格式

第1行为小行星个数n,第2行至第n+1行为xi, yi, zi,描述第i个小行星所在的位置。

输出格式

共1行,为消除所有行星的最少次数。


将方格图的二维转三维

 

将坐标的x,y,z依次建边
求最大流最小割
#include<bits/stdc++.h>
#define re return
#define ll long long
#define inc(i,l,r) for(int i=l;i<=r;++i)

const int inf=2147483647,maxn=5005;
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

int n,m,ans,s=3001,t=3002;
int hd[maxn],k=1,deep[maxn],cur[maxn]; 

struct node{
    int to,nt,flow;
}e[800005];

inline void add(int x,int y,int z)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].flow=z;
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].flow=0;
} 

inline bool bfs()
{
    inc(i,1,t)deep[i]=0;
    deep[s]=1;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!deep[v]&&e[i].flow)
            {
                deep[v]=deep[x]+1;
                if(v==t)re 1;
                q.push(v);
            }
        }
    }
    re 0;
}

inline int dfs(int x,int flow)
{
    if(x==t) re flow;
    int delta=flow;
    for(int &i=cur[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(deep[v]==deep[x]+1&&e[i].flow)
        {
            int d=dfs(v,min(e[i].flow,delta));
            e[i].flow-=d;e[i^1].flow+=d;
            delta-=d;
            if(!delta)re flow;
        }
    }
    re flow-delta;
}

int main()
{
    int x,y,z;
    rd(n);
    inc(i,1,500)
    {
        add(i,i+1500,1);
        add(s,i,inf);
    }
    
    inc(i,501,1000)add(i,i+1500,1);
    inc(i,1001,1500)
    {
        add(i,i+1500,1);
        add(i+1500,t,inf);
    }
    
    inc(i,1,n)
    {
        rd(x),rd(y),rd(z);
        add(x+1500,y+500,1);
        add(y+2000,z+1000,1);
    }
    
    while(bfs())
    {
        inc(i,1,t)cur[i]=hd[i];
        ans+=dfs(s,inf);
    }
    
    printf("%d",ans);
    re 0;
}

 

posted @ 2019-08-16 20:10  凉如水  阅读(155)  评论(0编辑  收藏  举报