• Luogu3227 HNOI2013切糕


    My blog

    Description

    link

    给定一个 (n,m,h) 的立方体,每个点有代价,现在在每个纵轴上面找一个点,使得所有的代价的和最小

    限制:相邻的纵轴上找的点的位置距离差不能超过一个给定的值 (d)

    Solution

    最小割,割掉的边是要切掉的点

    从源点向第一层的点连 (inf)

    这里还有一个点化边,然后新建一层,接着从上面一层的每一个点向下面的点连上一条边权为点的代价的边

    最后一层((h+1) 层)往汇点连一条边权为 (inf) 的边

    然后我们考虑怎么对付这个限制

    其实这个限制在图上就变成了我们在考虑一个 ((x,y,k)) 之后必须选 ((x+dx,y+dy,k pm d))

    啊这里 (dx)(dy) 表示四向相邻点

    那么就是必经边呗,连上个 (inf) 就成了

    然后跑个最小割就好了

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=1e5+10;
    	struct node{
    		int to,lim,nxt;
    	}e[N<<1];
    	int head[N],cnt=1,dep[N],S,T;
    	queue<int> Q;
    	inline void adde(int u,int v,int w)
    	{
    		e[++cnt].lim=w; e[cnt].nxt=head[u]; e[cnt].to=v;
    		return head[u]=cnt,void();
    	}
    	inline void add(int u,int v,int w){return adde(u,v,w),adde(v,u,0);}
    	inline bool bfs()
    	{
    		memset(dep,0,sizeof(dep)); dep[S]=1; 
    		while(Q.size()) Q.pop(); Q.push(S);
    		while(Q.size())
    		{
    			int fr=Q.front(); Q.pop();
    			for(int i=head[fr];i;i=e[i].nxt)
    			{
    				int t=e[i].to; 
    				if(e[i].lim&&!dep[t]) dep[t]=dep[fr]+1,Q.push(t);
    			}
    		} return dep[T];
    	}
    	inline int dfs(int now,int in)
    	{
    		int out=0; if(now==T) return in;
    		for(int i=head[now];in&&i;i=e[i].nxt)
    		{
    			int t=e[i].to; 
    			if(e[i].lim&&dep[now]==dep[t]-1) 
    			{
    				int res=dfs(t,min(e[i].lim,in));
    				in-=res; out+=res; e[i].lim-=res; e[i^1].lim+=res;
    			}
    		} if(!out) dep[now]=0;
    		return out;	
    	}
    	int v[110][110][100],p,q,r,d;
    	inline int id(int x,int y,int z){return p*q*(z-1)+y+(x-1)*q;}
    	int fx[4]={0,1,0,-1};
    	int fy[4]={1,0,-1,0};
    	inline bool in(int x,int y){return x>=1&&x<=p&&y>=1&&y<=q;}
    	signed main()
    	{
    		p=read(),q=read(); r=read(); d=read();
    		S=p*q*(r+1)+1,T=p*q*(r+1)+2; 
    		for(int k=1;k<=r;++k)
    		{
    			 for(int i=1;i<=p;++i)
    			{
    				for(int j=1;j<=q;++j) v[i][j][k]=read();
    			}
    		}
    		for(int i=1;i<=p;++i)
    		{
    			for(int j=1;j<=q;++j)
    			{
    				add(S,id(i,j,1),1e18+10);
    				for(int k=1;k<=r;++k) add(id(i,j,k),id(i,j,k+1),v[i][j][k]);
    				add(id(i,j,r+1),T,1e18+10); 
    			}
    		}
    		for(int i=1;i<=p;++i)
    		{
    			for(int j=1;j<=q;++j)
    			{
    				for(int k=0;k<4;++k)
    				{
    					int x=i+fx[k],y=j+fy[k];
    					if(!in(x,y)) continue;
    					for(int l=d+1;l<=r+1;++l) add(id(i,j,l),id(x,y,l-d),1e18+10);
    				}
    			}
    		}
    		int ans=0;
    		while(bfs()) ans+=dfs(S,1e18+10);
    		printf("%lld
    ",ans);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    

    Review

    限制可以转化成网络图上面的必经边,然后直接连 (inf) 边就好了

  • 相关阅读:
    CocoaPods的安装使用和常见问题
    超全iOS面试资料,看完你还担心面试吗?
    IOS--多线程之线程间通讯
    iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
    java之NIO编程
    libthrift0.9.0解析(四)之TThreadPoolServer&ServerContext
    android开发笔记
    rtsp转发服务器设计
    神经网络文献资料
    deep learning in nlp 资料文献
  • 原文地址:https://www.cnblogs.com/yspm/p/13116324.html
Copyright © 2020-2023  润新知