zoukankan      html  css  js  c++  java
  • Luogu2472 SCOI2007蜥蜴

    Description

    link

    Solution

    首先几个地方指向网络流的常见套路

    1.每个点有固定的经过次数:拆点,入点和出点之间连权值为次数的边

    然后把能相互跳的点之间连 (inf) 的边,(S) 往蜥蜴连 (1) 的边,能跳出去的点往 (T)(inf) 的边

    上面直接含义就能理解……

    然后最大流

    记得题目中的所求,所以应该是要用蜥蜴的数量减去 (maxflow)

    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 M=2e5+10,N=2e3+10;
    	struct node{
    		int to,lim,nxt;
    	}e[M];
    	int head[N],dep[N],cnt=1,n,m,d,S,T;
    	inline void add1(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 add1(u,v,w),add1(v,u,0);}
    	inline bool bfs()
    	{
    		queue<int> q;
    		memset(dep,0,sizeof(dep)); dep[S]=1; q.push(S);
    		while(!q.empty())
    		{
    			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)
    	{
    		if(now==T) return in; int out=0;
    		for(int i=head[now];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;
    	}
    	char s[N][N];
    	inline int id1(int x,int y){return (x-1)*m+y;}
    	inline int id2(int x,int y){return n*m+id1(x,y);}
    	inline int dis(int a,int b,int c,int d){return (a-c)*(a-c)+(b-d)*(b-d);}
    	signed main()
    	{
    		n=read(),m=read(),d=read();
    		S=n*m*2+1,T=n*m*2+2;
    		for(int i=1;i<=n;++i) 
    		{
    			for(int j=1;j<=m;++j)
    			{
    				cin>>s[i][j]; 
    				if(s[i][j]>'0') 
    				{
    					add(id1(i,j),id2(i,j),s[i][j]-'0');
    					if(i<=d||i>=n-d+1||j<=d||j>=m-d+1) 
    					{
    						add(id2(i,j),T,1e18+10);
    					}
    				}
    			} 
    		}
    		for(int i=1;i<=n;++i)
    		{
    			for(int j=1;j<=m;++j)
    			{
    				for(int k=1;k<=n;++k)
    				{
    					for(int l=1;l<=m;++l)
    					{
    						if(dis(i,j,k,l)<=d*d) add(id2(i,j),id1(k,l),1e18+10); 
    					}
    				}
    			}
    		}
    		int num=0,ans=0;
    		for(int i=1;i<=n;++i) 
    		{
    			for(int j=1;j<=m;++j) 
    			{
    				cin>>s[i][j]; 
    				if(s[i][j]=='L') 
    				{
    					num++;
    					add(S,id1(i,j),1); 
    				}
    			}
    		} 
    		while(bfs()) ans+=dfs(S,1e18+10);
    		cout<<num-ans<<endl;
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    MFC单文档框架分析及执行流程(转)
    MFC不同工程(解决方案)之间对话框资源的复制与重用方法(转)
    【DLL】动态库的创建,隐式加载和显式加载(转)
    H264协议(转)
    YUV颜色编码解析(转)
    windows下常用快捷键(转)
    【Sqlite3】SQLITE3使用总结(转)
    C++11 自动释放锁(转)
    alt+ F8 设置无效(转)
    Invalidate()(转)
  • 原文地址:https://www.cnblogs.com/yspm/p/13070145.html
Copyright © 2011-2022 走看看