zoukankan      html  css  js  c++  java
  • BZOJ4657 : tower

    显然只有横向和纵向的两个炮塔才有可能冲突。

    考虑最小割,将每个炮塔所有能攻击到的位置建点,相邻之间连无穷的边,表示前缀和关系,即选了一个点,就必须要选所有比它近的点。

    属于横向炮塔的点向$S$连边,容量为前缀最大值的差值;属于纵向炮塔的点向$T$连边,容量为前缀最大值的差值。

    对于一个交点,则在两个点之间连无穷边,表示必须舍弃其中一个。

    答案$=$总收益$-$最小割。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=126000,inf=~0U>>2;
    int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    struct E{int t,f;E*nxt,*pair;}*g[N],*d[N],pool[1000000],*cur=pool;
    int n,m,i,j,a[55][55],b[55][55],cnt,S,T,h[N],gap[N],ans;
    inline void add(int s,int t,int f){
      if(!f)return;
      if(f<inf)ans+=f;
      E*p=cur++;p->t=t;p->f=f;p->nxt=g[s];g[s]=p;
      p=cur++;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(E*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
        int ret=sap(p->t,min(flow-rec,p->f));
        p->f-=ret;p->pair->f+=ret;d[v]=p;
        if((rec+=ret)==flow)return flow;
      }
      if(!(--gap[h[v]]))h[S]=T;
      gap[++h[v]]++;d[v]=g[v];
      return rec;
    }
    inline void tag(int x,int y,int k){
      int mx=0,pre=0,now;
      while(1){
        x+=dx[k],y+=dy[k];
        if(x<1||x>n||y<1||y>m)return;
        cnt++;
        if(pre){
          if(k<2)add(cnt,pre,inf);
          else add(pre,cnt,inf);
        }
        if(k<2)add(S,cnt,max(mx,a[x][y])-mx);else add(cnt,T,max(mx,a[x][y])-mx);
        mx=max(mx,a[x][y]);
        pre=cnt;
        if(b[x][y]){
          if(k<2)add(cnt,b[x][y],inf);
          else add(b[x][y],cnt,inf);
        }else b[x][y]=cnt;
      }
    }
    int main(){
      scanf("%d%d",&n,&m);
      S=n*m*max(n,m)+1;T=S+1;
      for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);
      for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(a[i][j]<0)tag(i,j,a[i][j]+4);
      for(gap[0]=T,i=1;i<=T;i++)d[i]=g[i];
      while(h[S]<T)ans-=sap(S,inf);
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    POJ 1741 Tree(树分治)
    HDU 2196 Computer(树形dp)
    2015沈阳区域赛Meeting(最短路 + 建图)
    make the fence great again(dp 二维)
    2017沈阳区域赛Infinite Fraction Path(BFS + 剪枝)
    bitset详解
    2016青岛区域赛.Coding Contest(费用流 + 概率计算转换为加法计算)
    2019上海网络赛B题(差分 + 离散化 or 差分 + 思维)
    poj-1664.放苹果.(递推)
    hdu-4738.Caocao's Bridges(图中权值最小的桥)
  • 原文地址:https://www.cnblogs.com/clrs97/p/5723755.html
Copyright © 2011-2022 走看看