BZOJ3144: [Hnoi2013]切糕

来源:互联网 发布:淘宝开保健品店的条件 编辑:程序博客网 时间:2024/04/25 08:25

这是个最小割的经典模型?
嗯如果不考虑相邻切点那个要求距离D,那么就是在每个纵轴上找一个最小的,如果用最小割,可以源连向每个纵轴最上的点,然后每个纵轴互相独立,从上至下,向下一层连,容量为点权,最小割即答案
如果考虑相邻切点高度距离差不大于D的限制,每个纵轴上的点就向它上方相邻纵轴高度差D的点连容量无限的边,这样可以限制,原因见图,这篇题解写的挺详细的 既然这篇题解写的这么详细我写这个还有什么意义...

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;int _min(int x,int y){return x<y?x:y;}const int maxn = 45;const int maxp = maxn*maxn*maxn;struct edge{    int y,c,nex;    edge(){}    edge(int _y,int _c,int _nex){y=_y;c=_c;nex=_nex;}}a[maxp*12]; int len,fir[maxp],fi[maxp];int n,m,R,D,st,ed;void ins(int x,int y,int c){    a[++len]=edge(y,c,fir[x]); fir[x]=len;    a[++len]=edge(x,0,fir[y]); fir[y]=len;}int h[maxp];queue<int>Q;bool bfs(){    memset(h,0,sizeof h); h[st]=1;    Q.push(st);    while(!Q.empty())    {        int x=Q.front(); Q.pop();        for(int k=fir[x];k;k=a[k].nex)        {            int y=a[k].y;            if(a[k].c&&!h[y]) h[y]=h[x]+1,Q.push(y);        }    }    return h[ed]>0;}int dfs(int x,int flow){    if(x==ed) return flow;    int delta=0;    for(int &k=fi[x];k;k=a[k].nex)    {        int y=a[k].y;        if(a[k].c&&h[y]==h[x]+1)        {            int minx=dfs(y,_min(flow-delta,a[k].c));            a[k].c-=minx; a[k^1].c+=minx;            delta+=minx;        }        if(delta==flow) return delta;    }    if(!delta) h[x]=0;    return delta;}int nm,Dnm;int gid(int x,int y,int z) {return (z-1)*nm+(x-1)*m+y;}int main(){    memset(fir,0,sizeof fir); len=1;    scanf("%d%d%d",&n,&m,&R); st=n*m*R+1,ed=st+1; nm=n*m;    scanf("%d",&D); Dnm=nm*D;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            ins(st,gid(i,j,1),inf);    for(int k=1;k<=R;k++)    {        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                int x; scanf("%d",&x);                int id=gid(i,j,k);                if(k<R) ins(id,id+nm,x);                else ins(id,ed,x);                if(j>1&&k>D) ins(id,id-Dnm-1,inf);                if(j<m&&k>D) ins(id,id-Dnm+1,inf);                if(i>1&&k>D) ins(id,id-Dnm-m,inf);                if(i<n&&k>D) ins(id,id-Dnm+m,inf);            }        }    }    int r=0;    while(bfs())    {        for(int i=1;i<=ed;i++) fi[i]=fir[i];        r+=dfs(st,inf);    }    printf("%d\n",r);    return 0;}
0 0
原创粉丝点击