ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【POJ2195】Going Home

2021-07-31 12:02:20  阅读:219  来源: 互联网

标签:code const int Going Maxn Maxm Home include POJ2195


题目

解析:

本质是个二分图带权匹配问题,建图后用费用流实现即可。

code:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;

const int Maxn=205;
const int Maxm=10205;
const int inf=1e9;
int n,m,size,s,t,sum,tot1,tot2;
char c;
int dis[Maxn],v[Maxn],first[Maxn],tmp[Maxn];
struct shu{int to,next,l,c;}e[Maxm<<1];
struct zb{int x,y;}p1[Maxn],p2[Maxn];

inline int calc(int i,int j) {return abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y);}

inline void add(int x,int y,int l,int c)
{
	e[++size].next=first[x],first[x]=size,e[size].to=y,e[size].l=l,e[size].c=c;
}

inline void init()
{
	tot1=tot2=0;
	for(int i=1;i<=n;i++)
	{
	  for(int j=1;j<=m;j++)
	  {
	     scanf("%c",&c);
	     if(c=='H') p2[++tot2].x=i,p2[tot2].y=j;
	     if(c=='m') p1[++tot1].x=i,p1[tot1].y=j;
	  }
	  scanf("\n");
	}
	t=2*tot1+1,sum=0,size=-1;
	for(int i=s;i<=t;i++) first[i]=-1;
	for(int i=1;i<=tot1;i++)
	{
	  add(s,i,1,0),add(i,s,0,0);
	  for(int j=1;j<=tot2;j++) add(i,tot1+j,1,calc(i,j)),add(tot1+j,i,0,-calc(i,j));
	}
	for(int i=1;i<=tot2;i++) add(tot1+i,t,1,0),add(t,tot1+i,0,0);
}

inline bool spfa()
{
	queue<int>q;
	for(int i=s;i<=t;i++) tmp[i]=first[i],dis[i]=inf;
	q.push(s),v[s]=1,dis[s]=0;
	while(!q.empty())
	{
	  int p=q.front();q.pop(),v[p]=0;
	  for(int u=first[p];~u;u=e[u].next)
	  {
	  	int to=e[u].to;
	  	if(dis[to]<=dis[p]+e[u].c || !e[u].l) continue;
	  	dis[to]=dis[p]+e[u].c;
	  	if(!v[to]) q.push(to),v[to]=1;
	  }
	}
	return dis[t]!=inf;
}

inline int dfs(int p,int flow)
{
	if(p==t) return flow;
	int s=0;v[p]=1;
	for(int &u=tmp[p];~u;u=e[u].next)
	{
	  int to=e[u].to;
	  if(v[to] || dis[to]!=dis[p]+e[u].c || !e[u].l) continue;
	  int minn=dfs(to,min(flow-s,e[u].l));
	  e[u].l-=minn,e[u^1].l+=minn,sum+=minn*e[u].c,s+=minn;
	  if(s==flow) break;
	}
	v[p]=0;
	return s;
}

inline void solve()
{
	while(spfa()) {while(dfs(s,inf));}
}

int main()
{
	while(1)
	{
	  scanf("%d%d\n",&n,&m);
	  if(!n) break;
	  init();
	  solve();
	  cout<<sum<<"\n";
	}
	return 0;
}

标签:code,const,int,Going,Maxn,Maxm,Home,include,POJ2195
来源: https://www.cnblogs.com/Tarjan-Zeng/p/15083831.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有