zoukankan      html  css  js  c++  java
  • BZOJ3630 : [JLOI2014]镜面通道

    从左边不能到达右边当且仅当存在一条与上下底边相连的分割线将它们分开

    设下底边为S,上底边为T,每个元件作为点,有公共部分的两个点互相连边

    最后拆点求最小割

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=620,inf=~0U>>2;
    int n,i,j,x,y,S,T,h[N],gap[N],ans;
    struct P{int x1,y1,x2,y2,r,t,x,y;}a[N];
    struct edge{int t,f;edge *nxt,*pair;}*g[N],*d[N];
    inline void add(int s,int t,int f){
      edge *p=new(edge);p->t=t;p->f=f;p->nxt=g[s];g[s]=p;
      p=new(edge);p->t=s;p->f=0;p->nxt=g[t];g[t]=p;
      g[s]->pair=g[t];g[t]->pair=g[s];
    }
    int sap(int v,int flow){
      if(v==T)return flow;
      int rec=0;
      for(edge*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
        int ret=sap(p->t,std::min(flow-rec,p->f));
        p->f-=ret;p->pair->f+=ret;d[v]=p;
        if((rec+=ret)==flow)return flow;
      }
      d[v]=g[v];
      if(!(--gap[h[v]]))h[S]=T;
      gap[++h[v]]++;
      return rec;
    }
    inline int sqr(int x){return x*x;}
    inline double dis(int x1,int y1,int x2,int y2){return sqrt(sqr(x1-x2)+sqr(y1-y2))-1e-8;}
    inline bool check(P a,P b){
      if(a.t==1&&b.t==1)return dis(a.x,a.y,b.x,b.y)<=1.0*a.r+b.r;
      if(a.t==2&&b.t==1){P c=a;a=b;b=c;}
      if(a.t==1&&b.t==2){
        if(dis(a.x,a.y,b.x1,b.y1)<=a.r)return 1;
        if(dis(a.x,a.y,b.x1,b.y2)<=a.r)return 1;
        if(dis(a.x,a.y,b.x2,b.y1)<=a.r)return 1;
        if(dis(a.x,a.y,b.x2,b.y2)<=a.r)return 1;
        if(b.x2>a.x&&b.x1<a.x)if(fabs(b.y2-a.y)<=a.r||fabs(b.y1-a.y)<=a.r)return 1;
        if(b.y2>a.y&&b.y1<a.y)if(fabs(b.x2-a.x)<=a.r||fabs(b.x1-a.x)<=a.r)return 1;
        return b.x1<=a.x&&a.x<=b.x2&&b.y1<=a.y&&a.y<=b.y2;
      }
      return !(b.x2<a.x1||b.x1>a.x2||b.y2<a.y1||b.y1>a.y2);
    }
    int main(){
      scanf("%d%d%d",&x,&y,&n);S=n*2+1,T=S+1;
      for(i=1;i<=n;i++)add(i,i+n,1),add(i+n,i,1);
      a[0].t=2,a[0].y1=-1,a[0].x2=x;
      a[n+1].t=2,a[n+1].y1=y,a[n+1].x2=x,a[n+1].y2=y+1;
      for(i=1;i<=n;i++){
        scanf("%d",&a[i].t);
        if(a[i].t==1)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].r);else scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
        for(j=1;j<i;j++)if(check(a[i],a[j]))add(i+n,j,inf),add(j+n,i,inf);
      }
      for(i=1;i<=n;i++)if(check(a[i],a[0]))add(S,i,inf);
      for(i=1;i<=n;i++)if(check(a[i],a[n+1]))add(i+n,T,inf);
      for(gap[i=0]=T;i<=T;i++)d[i]=g[i];
      while(h[S]<T)ans+=sap(S,inf);
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    函数
    数值
    数据类型
    jQuery工具方法
    jQuery概述
    史上最全的SpringMVC学习笔记
    webpack-Hot Module Replacement(热更新)
    webpack-Manifest
    webpack-Targets(构建目标)
    webpack-Dependency Graph(依赖图)
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403191.html
Copyright © 2011-2022 走看看