zoukankan      html  css  js  c++  java
  • HDU2732 Leapin' Lizards 网络流 最大流 SAP

    原文链接http://www.cnblogs.com/zhouzhendong/p/8362002.html


    题目传送门 - HDU2732


    题意概括

      给你一个网格,网格上的一些位置上有一只蜥蜴,所有蜥蜴的最大跳跃距离是d,如果一只蜥蜴能跳出网格边缘,那么它就安全了.且每个网格有一个最大跳出次数x,即最多有x只蜥蜴从这个网格跳出,这个网格就再也不能有蜥蜴进来了.问你最少有多少只蜥蜴跳不出网格.

    (摘自http://blog.csdn.net/u013480600/article/details/38964749)


    题解

      我们考虑到每一个点有限制经过次数,自然想到网络流。

      对于点限流,我们自然是拆点。(套路)

      于是,一个点拆成两个点,连一条边,容量为点的限流。

      我们考虑只有原来就有蜥蜴的点才能拥有初始流量,所以对于每一个有蜥蜴的点,从源点连一条容量为1的边。

      我们考虑从一个点跳到其他的点:

        如果可以直接跳出去,那自然是直接跳出去好,所以从该点向汇点连一条容量为INF的边。

        如果不能,那么流连向所有可以到达的点,容量为INF。

     

      这个输出分类很恶心,我因为no的地方加了个s而找错很久。

      主要是我一直在信心慢慢的找网络流和构图的错误……我认为我的输出一定不会错的……然后就……


    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    const int N=1005,M=N*N*3,INF=1e9;
    struct edge{
    	int x,y,cap,flow,nxt;
    };
    struct gragh{
    	int cnt,fst[N],dist[N],n,S,T,num[N],cur[N],p[N];
    	int q[N],head,tail;
    	edge e[M];
    	void set(int _S,int _T,int _n){
    		S=_S,T=_T,n=_n,cnt=1;
    		memset(fst,0,sizeof fst);
    	}
    	void add(int a,int b,int c){
    		cnt++;
    		e[cnt].x=a,e[cnt].y=b,e[cnt].cap=c,e[cnt].flow=0;
    		e[cnt].nxt=fst[a],fst[a]=cnt;
    		cnt++;
    		e[cnt].x=b,e[cnt].y=a,e[cnt].cap=0,e[cnt].flow=0;
    		e[cnt].nxt=fst[b],fst[b]=cnt;
    	}
    	void bfs(){
    		memset(dist,-1,sizeof dist);
    		head=tail=dist[T]=0;
    		q[++tail]=T;
    		while (head<tail)
    			for (int x=q[++head],y,i=fst[x];i;i=e[i].nxt)
    				if ((i&1)&&dist[y=e[i].y]==-1)
    					dist[q[++tail]=y]=dist[x]+1;
    		for (int i=1;i<=n;i++)
    			if (dist[i]==-1)
    				dist[i]=n;
    	}
    	void init(){
    		bfs();
    		memset(num,0,sizeof num);
    		for (int i=1;i<=n;i++)
    			num[dist[i]]++,cur[i]=fst[i];
    	}
    	int Augment(int &x){
    		int ex_flow=INF;
    		for (int i=T;i!=S;i=e[p[i]].x)
    			if (e[p[i]].cap-e[p[i]].flow<=ex_flow)
    				ex_flow=e[p[i]].cap-e[p[i]].flow,x=e[p[i]].x;
    		for (int i=T;i!=S;i=e[p[i]].x)
    			e[p[i]].flow+=ex_flow,e[p[i]^1].flow-=ex_flow;
    		return ex_flow;
    	}
    	int ISAP(){
    		int x=S,y,MaxFlow=0;
    		init();
    		while (dist[S]<n){
    			if (x==T){
    				MaxFlow+=Augment(x);
    				continue;
    			}
    			bool found=0;
    			for (int i=cur[x];i;i=e[i].nxt)
    				if (dist[y=e[i].y]+1==dist[x]&&e[i].cap>e[i].flow){
    					cur[x]=p[y]=i,x=y,found=1;
    					break;
    				}
    			if (!found){
    				int d=n+1;
    				for (int i=fst[x];i;i=e[i].nxt)
    					if (e[i].cap>e[i].flow)
    						d=min(d,dist[e[i].y]+1);
    				if (!--num[dist[x]])
    					return MaxFlow;
    				num[dist[x]=d]++,cur[x]=fst[x],x=x==S?x:e[p[x]].x;
    			}
    		}
    		return MaxFlow;
    	}
    }g;
    int T,n,m,d,Case=0;
    char r1[25][25],r2[25][25];
    bool Out(int x,int y){
    	return min(min(x,n+1-x),min(y,m+1-y))<=d;
    }
    int Ha(int x,int y,int in){
    	return in*n*m+(x-1)*m+y;
    }
    void solve(){
    	int S,T;
    	scanf("%d%d",&n,&d);
    	for (int i=1;i<=n;i++)
    		scanf("%s",r2[i]+1);
    	for (int i=1;i<=n;i++)
    		scanf("%s",r1[i]+1);
    	m=strlen(r1[1]+1);
    	g.set(S=n*m*2+1,T=n*m*2+2,n*m*2+2);
    	int ans=0;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++){
    			if (r1[i][j]=='L')
    				g.add(S,Ha(i,j,0),1),ans++;
    			g.add(Ha(i,j,0),Ha(i,j,1),r2[i][j]-'0');
    		}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++){
    			if (Out(i,j))
    				g.add(Ha(i,j,1),T,INF);
    			else
    				for (int x=1;x<=n;x++)
    					for (int y=1;y<=m;y++)
    						if ((x!=i||y!=j)&&sqrt((i-x)*(i-x)+(j-y)*(j-y))<=d)
    							g.add(Ha(i,j,1),Ha(x,y,0),INF);
    		}
    	ans-=g.ISAP();
    	printf("Case #%d: ",++Case);
    	if (ans==0)
    		printf("no lizard was left behind.
    ");
    	if (ans==1)
    		printf("1 lizard was left behind.
    ");
    	if (ans>1)
    		printf("%d lizards were left behind.
    ",ans);
    }
    int main(){
    	scanf("%d",&T);
    	while (T--)
    		solve();
    	return 0;
    }
    

      

  • 相关阅读:
    Working with WordprocessingML documents (Open XML SDK)
    How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
    Azure:Manage anonymous read access to containers and blobs
    Convert HTML to PDF with New Plugin
    location.replace() keeps the history under control
    On the nightmare that is JSON Dates. Plus, JSON.NET and ASP.NET Web API
    HTTP Modules versus ASP.NET MVC Action Filters
    解读ASP.NET 5 & MVC6系列(6):Middleware详解
    Content Negotiation in ASP.NET Web API
    Action Results in Web API 2
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU2732.html
Copyright © 2011-2022 走看看