Live2d Test Env

ZOJ1654 Place the Robots

                                                                                               Zoj1654

标准解法:二分匈牙利。

写法各异嘛,看不懂或者懒得看也正常,如果想了解我思路的可以和我讨论的。

在练习sap,所以还是写了一遍:

 

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<memory.h>
#include<cmath>
using namespace std;
char c[51][51];
const int M=1000000;

int L,R,s,t,cnt;
int a[51][51],b[51][51];//a是x轴的标号,b是y的 
const int inf=1000000;
int vd[2501],dis[2501],ans,m,n;
int Laxt[M],Next[M],Val[M],To[M];
void _update()
{
	memset(vd,0,sizeof(vd));
	memset(dis,0,sizeof(dis));
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
        memset(To,0,sizeof(To));
        memset(Laxt,0,sizeof(Laxt));
        memset(Next,0,sizeof(Next));
	memset(Val,0,sizeof(Val));
	ans=0;
	cnt=2;
	s=0;
}
int dfs(int u,int flow)
{    
      int temp,delta;
      if(u==t)return flow;
      delta=0;
      for(int i=Laxt[u];i>0;i=Next[i]) //这里的0限制了cnt不从0开始 
         if(Val[i]>0 && dis[u]==dis[To[i]]+1) 
         {
             temp=dfs(To[i],min(flow-delta,Val[i]));
             Val[i]-=temp;
             Val[i^1]+=temp;

             delta+=temp;
             if(delta==flow||dis[s]>t) return delta;
         }
      vd[dis[u]]--;
      if(vd[dis[u]]==0)dis[s]=t+1;
      dis[u]++;
      vd[dis[u]]++;
      return delta;
}
void _bh()//标号
{
	    L=0;
		for(int i=1;i<=n;i++)
		{
		    bool ok=false;
		    for(int j=1;j<=m;j++)
		     if(ok&&c[i][j]!='#') a[i][j]=L;
		     else if(ok&&c[i][j]=='#') ok=false;
		     else if(!ok&&c[i][j]!='#') {
					a[i][j]=++L;
					ok=true;
		     }
		}
		R=L;
		 for(int i=1;i<=m;i++)
		{
		    bool ok=false;
		    for(int j=1;j<=n;j++)
		     if(ok&&c[j][i]!='#') b[j][i]=R;
		     else if(ok&&c[j][i]=='#') ok=false;
		     else if(!ok&&c[j][i]=='o') {
					b[j][i]=++R;
					ok=true;
		     }
	 }
		t=R+1;
} 
void _add(int u,int v,int w)
{
	Next[cnt]=Laxt[u];
	Laxt[u]=cnt;
	To[cnt]=v;
	Val[cnt++]=w;
	
	Next[cnt]=Laxt[v];
	Laxt[v]=cnt;
	To[cnt]=u;
	Val[cnt++]=0;
}
int main()
{
	int T;
	cin>>T;
	for(int tt=1;tt<=T;tt++){
		cin>>n>>m;
		_update();
		for(int i=1;i<=n;i++)
		 for(int j=1;j<=m;j++)
		  cin>>c[i][j];
	    _bh();
		for(int i=1;i<=n;i++)
		 for(int j=1;j<=m;j++)
		  if(c[i][j]=='o')
			_add(a[i][j],b[i][j],1);
		for(int i=1;i<=L;i++)
		 _add(s,i,1);
		for(int i=L+1;i<=+R;i++)
		 _add(i,t,1);
	  while(dis[s]<t+1)
      {
         int flow=dfs(s,inf);
         ans+=flow;
      }
		printf("Case :%d\n%d\n",tt,ans);
	}
	return 0;
}

 

posted @ 2017-09-27 21:06  nimphy  阅读(152)  评论(0编辑  收藏  举报