• cogs 2398 切糕 最小割


    cogs 2398 切糕
    题解:
    若没有D的限制,我们建模应该是这样的。
    1
    跑一个最小割即可。
    有了D的限制,那么存在点对(i,j)要求i,j的割边距离差不能超过D,假设D是1,图应该是这样。
    2
    如果割断了v(1,1)是不会割断v(2,3)的,我们假设割断的是v(2,3)那么此时会有一条路从v(2,2)的后继点到达v(1,1)的后继点,此时整张图还没有被割断,而每行边我们只割断一条,所以这不是一个合法的割,所以不会割断v(2,3)。
    所以就是让第i行编号为k的点向第j行编号为k-D的点连一条INF的边就好。
    code

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define fcl fclose(stdin); fclose(stdout); return 0
    void Read(int& x){
    	char ch; while(ch=getchar(),ch<'0'||ch>'9');
    	x=ch-'0'; while(ch=getchar(),ch>='0'&&ch<='9') x=x*10+ch-'0';
    }
    int P,Q,R,D;
    int v[50][50][50];
    int S,T;
    struct EDGE{
    	int to,next,flow;
    }edge[700010];
    int head[64010],tot=1;
    inline void AddEdge(int a,int b,int c){
    	edge[++tot].to=b;
    	edge[tot].flow=c;
    	edge[tot].next=head[a];
    	head[a]=tot;
    }
    inline void Add(int a,int b,int c){
    	AddEdge(a,b,c); AddEdge(b,a,0);
    }
    #define ty (edge[x].to)
    int cur[64010],dis[64010],Que[64010];
    const int INF=0x7f7f7f7f;
    bool Bfs(){
    	memset(dis,0x7f,(T+1)<<2); dis[S]=0;
    	int s=1,t=1,u; Que[1]=S;
    	while(s<=t){
    		u=Que[s++];
    		for(int x=head[u];x;x=edge[x].next)
    			if(edge[x].flow&&dis[ty]==INF)
    				dis[ty]=dis[u]+1,Que[++t]=ty;
    	}
    	return dis[T]!=INF;
    }
    int Dfs(int u,int a){
    	if(u==T||a==0) return a;
    	int f2=0,f;
    	for(int& x=cur[u];x;x=edge[x].next){
    		if(edge[x].flow&&dis[ty]==dis[u]+1){
    			f=Dfs(ty,min(a,edge[x].flow));
    			edge[x].flow-=f; edge[x^1].flow+=f;
    			f2+=f; a-=f;
    			if(a==0) break;
    		}
    	}
    	return f2;
    }
    int MinCut(){
    	int res=0;
    	while(Bfs()){
    		memcpy(cur,head,(T+1)<<2);
    		res+=Dfs(S,INF);
    	}
    	return res;
    }
    int main(){
    	freopen("nutcake.in","r",stdin);
    	freopen("nutcake.out","w",stdout);
    	
    	scanf("%d%d%d%d",&P,&Q,&R,&D);
    	int i,j,k,p;
    	for(k=1;k<=R;++k)
    		for(i=1;i<=P;++i)
    			for(j=1;j<=Q;++j)
    				Read(v[i][j][k]);
    	S=P*Q*R+1,T=S+1;
    	for(i=1;i<=P;++i){
    		for(j=1;j<=Q;++j){
    			p=(i-1)*Q+j;
    			Add(S,p,INF);
    			for(k=1;k<R;++k,p+=P*Q)
    				Add(p,p+P*Q,v[i][j][k]);
    			Add(p,T,v[i][j][R]);
    			for(k=1+D,p=(i-1)*Q+j+D*P*Q;k<=R;++k,p+=P*Q){
    				if(i>1) Add(p,(i-2)*Q+j+(k-D-1)*P*Q,INF);
    				if(i<P) Add(p,i*Q+j+(k-D-1)*P*Q,INF);
    				if(j>1) Add(p,(i-1)*Q+j-1+(k-D-1)*P*Q,INF);
    				if(j<Q) Add(p,(i-1)*Q+j+1+(k-D-1)*P*Q,INF);
    			}
    		}
    	}
    	printf("%d
    ",MinCut());
    	fcl;
    }
    
  • 相关阅读:
    简单的嵌套循环
    七、 二进制位运算
    六、字符串格式化--------列表常用操作
    JavaScript取消默认控件并添加新控件(DOM编程艺术第11章)
    JavaScript 字符串拼接 & setInterval()实现简单动画
    伪站创建代码-山东理工
    CSS常用样式
    CSS基础知识
    HTML5其他标签应用
    HTML表单的应用
  • 原文地址:https://www.cnblogs.com/kito/p/7135634.html
Copyright © 2020-2023  润新知