zoukankan      html  css  js  c++  java
  • bzoj 3144 切糕 —— 最小割

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

    每个点拆成 R 个,连成一条链,边上是权值,割掉代表选这一层;

    然后每个点的第 t 层向四周的点的第 t-d 层连边,就能达到选了第 i 条边,则四周的点必须选 i-d ~ T 范围的边,而对方反过来一连,就限制在 i-d ~ i+d 了;

    竟然因为忘记 ct=1 而调了一小时呵呵...

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int const xn=64005,xm=xn*10,inf=1e9;
    int n,m,H,hd[xn],ct=1,to[xm],nxt[xm],c[xm],dis[xn],cur[xn],S,T;
    queue<int>q;
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    void ade(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; c[ct]=z;}
    void add(int x,int y,int z){ade(x,y,z); ade(y,x,0);}
    int id(int x,int y,int k){return ((x-1)*m+y-1)*H+k;}
    bool bfs()
    {
      for(int i=S;i<=T;i++)dis[i]=0;
      dis[S]=1; q.push(S);
      while(q.size())
        {
          int x=q.front(); q.pop();
          for(int i=hd[x],u;i;i=nxt[i])
        if(!dis[u=to[i]]&&c[i])dis[u]=dis[x]+1,q.push(u);
        }
      return dis[T];
    }
    int dfs(int x,int fl)
    {
      if(x==T)return fl;
      int ret=0;
      for(int &i=cur[x],u;i;i=nxt[i])
        {
          if(dis[u=to[i]]!=dis[x]+1||!c[i])continue;
          int tmp=dfs(u,min(fl-ret,c[i]));
          if(!tmp)dis[u]=0;
          c[i]-=tmp; c[i^1]+=tmp;
          ret+=tmp; if(ret==fl)break;
        }
      return ret;
    }
    int main()
    {
      n=rd(); m=rd(); H=rd(); int d=rd(); S=0; T=n*m*H+1;
      for(int t=1;t<=H;t++)
        for(int i=1;i<=n;i++)
          for(int j=1,x;j<=m;j++)
        {
          x=rd(); int nw=id(i,j,t);
          if(t==1)add(S,nw,x); else add(id(i,j,t-1),nw,x);
          if(t==H)add(nw,T,inf); 
          if(t<=d)continue; int k=t-d;//
          if(i>1)add(nw,id(i-1,j,k),inf);
          if(j>1)add(nw,id(i,j-1,k),inf);
          if(i<n)add(nw,id(i+1,j,k),inf);
          if(j<m)add(nw,id(i,j+1,k),inf);
        }
      int ans=0;
      while(bfs())
        {
          memcpy(cur,hd,sizeof hd);
          ans+=dfs(S,inf);
        }
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    都不敢上CSDN了
    什么是函数(function)?
    今天3/8妇女节
    一件有意思的事情:关于std::string和std::auto_ptr
    转两篇Link相关的文章
    DevIL Downloads
    状态模式(State Pattern)
    访问者模式(Visitor Pattern)
    羊皮卷的故事第二章
    备忘录模式(Memento Pattern)
  • 原文地址:https://www.cnblogs.com/Zinn/p/10165307.html
Copyright © 2011-2022 走看看