zoukankan      html  css  js  c++  java
  • 【BZOJ3144】切糕(网络流,最小割)

    【BZOJ3144】切糕(网络流,最小割)

    题面

    BZOJ

    题解

    这样的类型很有趣
    先不考虑相邻距离差不能超过(D)的限制
    我们考虑答案,显然就是在每个位置选一个最小的高度割就行了
    化成最小割的模型?
    对于每个位置挂一条长链,分别表示每个高度
    (S)(1)高度相连,(R)高度和(T)相连
    连向第(i)个点的边的容量就是高度(i)的代价

    现在加入了距离不超过(D)的限制
    举个例子,如果你一个割掉了(1),那么,另外一个就不能割(1+D)
    也就是在(D)之后的那条边不能割
    如果割了的话,我们强制给他增加一条容量为(inf)的边让他不能这样割就好了
    这样子我们从(D+1)(1)连一条容量为(inf)的边
    这样子就不能割掉(1)再割(D+1)
    否则就还需要把这条(inf)的边给割掉,这样就保证了相邻的距离不超过(D)

    直接求最小割就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define inf 1000000000
    #define MAX 50
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int V[MAX][MAX][MAX],P,Q,R,D;
    int S,T,bh[MAX][MAX][MAX],tot;
    struct Line{int v,next,w;}e[5000000];
    int h[MAX*MAX*MAX],cnt=2;
    inline void Add(int u,int v,int w)
    {
    	e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
    	e[cnt]=(Line){u,h[v],0};h[v]=cnt++;
    }
    int level[MAX*MAX*MAX];
    bool bfs()
    {
    	queue<int> Q;Q.push(S);
    	for(int i=S;i<=T;++i)level[i]=0;level[S]=1;
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=h[u];i;i=e[i].next)
    			if(!level[e[i].v]&&e[i].w)
    				level[e[i].v]=level[u]+1,Q.push(e[i].v);
    	}
    	return level[T];
    }
    int dfs(int u,int flow)
    {
    	if(u==T||!flow)return flow;
    	int ret=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(level[v]==level[u]+1)
    		{
    			int d=dfs(v,min(flow,e[i].w));
    			ret+=d;flow-=d;
    			e[i].w-=d;e[i^1].w+=d;
    			if(!flow)break;
    		}
    	}
    	if(!ret)level[u]=0;
    	return ret;
    }
    int Dinic()
    {
    	int ret=0;
    	while(bfs())ret+=dfs(S,inf);
    	return ret;
    }
    int main()
    {
    	P=read();Q=read();R=read();D=read();
    	for(int i=1;i<=R;++i)
    		for(int j=1;j<=P;++j)
    			for(int k=1;k<=Q;++k)
    				V[j][k][i]=read(),bh[j][k][i]=++tot;
    	S=0;T=P*Q*R+1;
    	for(int i=1;i<=P;++i)
    		for(int j=1;j<=Q;++j)
    			Add(S,bh[i][j][1],V[i][j][1]);
    	for(int i=2;i<=R;++i)
    		for(int j=1;j<=P;++j)
    			for(int k=1;k<=Q;++k)
    				Add(bh[j][k][i-1],bh[j][k][i],V[j][k][i]);
    	for(int i=1;i<=P;++i)
    		for(int j=1;j<=Q;++j)
    			Add(bh[i][j][R],T,inf);
    	for(int i=1;i<=P;++i)
    		for(int j=1;j<=Q;++j)
    			for(int k=D+1;k<=R;++k)
    			{
    				if(i!=1)Add(bh[i][j][k],bh[i-1][j][k-D],inf);
    				if(j!=1)Add(bh[i][j][k],bh[i][j-1][k-D],inf);
    				if(i!=P)Add(bh[i][j][k],bh[i+1][j][k-D],inf);
    				if(j!=Q)Add(bh[i][j][k],bh[i][j+1][k-D],inf);
    			}
    	printf("%d
    ",Dinic());
    	return 0;
    }
    
    
  • 相关阅读:
    k8s与监控--解读prometheus监控kubernetes的配置文件
    一天学习k8s
    Kubernetes入门:Pod、节点、容器和集群
    skywalking的核心概念
    skywalking的插件管理agent管理
    skywalking7 源码解析 (3) :agent启动服务分析以及性能影响
    HyperLedger Fabric 多机部署(一)
    Hyperledger Fabric 替换couchDB
    Hyperledger Fabric (1.0)环境部署 chaincode【转】
    Hyperledger Fabric 第一次安装
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9085219.html
Copyright © 2011-2022 走看看