Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 22076 | Accepted: 11148 |
Description
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point.
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28
Source
題意:有n*m的矩陣,H表示這個點是一個房子,m表示這個點是一個人,現在每一個人需要走入一個房間,已經知道的是認得數目和房子的個數一定是相同的,現在問這些人都回到一個房間所走的總的步數最小
分析:找這些人到這些房子的最小步數,我們可以建一個超級源點和超級匯點,源點到每個人的費用爲0,距離爲1
每個房子到匯點費用爲0,距離爲1,人到房子的距離是1,費用爲座標差的和
//數組開大一些
#include <stdio.h>
#include <string.h>
#include <queue>
#include <stdlib.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 300
struct node
{
int u,v,cap,cost,next;
}eg[N*N];
struct node1
{
int x,y;
}q1[N*N],q2[N*N];
char mp[200][200];
int head[N],vis[N],dis[N],pre[N];
int top;
void add(int u,int v,int cap,int cost)
{
eg[top].u=u;
eg[top].v=v;
eg[top].cap=cap;
eg[top].cost=cost;
eg[top].next=head[u];
head[u]=top++;
eg[top].u=v;
eg[top].v=u;
eg[top].cap=0;
eg[top].cost=-cost;
eg[top].next=head[v];
head[v]=top++;
}
int spfa(int s,int t)
{
int i,j;
for(i=1;i<=t;i++)
{
dis[i]=inf;
pre[i]=-1;
vis[i]=0;
}
int q[112345];
int in=0,out=0;
q[in++]=s;
dis[s]=0;
vis[s]=1;
while(in>out)
{
int u=q[out++];
vis[u]=0;
for(i=head[u];i!=-1;i=eg[i].next)
{
if(eg[i].cap>0)
{
int v=eg[i].v;
if(dis[v]>dis[u]+eg[i].cost)
{
dis[v]=dis[u]+eg[i].cost;
pre[v]=i; //i指的是以v爲終點這條邊在eg中的編號
if(!vis[v])
{
vis[v]=1;
q[in++]=v;
}
}
}
}
}
if(dis[t]==inf)return 0;
else return dis[t];
}
int sap(int s,int t)
{
int i;
int ans=0,max_flow=0;
int flow;
while(spfa(s,t))
{
for(i=1;i<=t;i++)
printf("%d %d \n",i,pre[i]);
top=0;
flow=inf;
for(i=pre[t];i!=-1;i=pre[eg[i].u])
if(eg[i].cap<flow)
flow=eg[i].cap;
for(i=pre[t];i!=-1;i=pre[eg[i].u])
{
eg[i].cap-=flow;
eg[i^1].cap+=flow;
}
ans+=dis[t];
max_flow+=flow;
}
return ans;
}
int main()
{
int n,m,i,j;
while(~scanf("%d%d",&n,&m))
{
top=0;
memset(head,-1,sizeof(head));
int top1=0,top2=0;
if(n==0&&m==0)
break;
for(i=0;i<n;i++)
{
scanf("%s",mp[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mp[i][j]=='m')
{
q1[top1].x=i;
q1[top1++].y=j;
}
else if(mp[i][j]=='H')
{
q2[top2].x=i;
q2[top2++].y=j;
}
}
}
for(i=0;i<top1;i++)
{
add(1,i+2,1,0);
for(j=0;j<top2;j++)
{
int l=abs(q1[i].x-q2[j].x)+abs(q1[i].y-q2[j].y);
//printf(" %d\n",l);
add(i+2,top1+j+2,1,l);
}
}
for(j=0;j<top2;j++)
add(top1+j+2,top1+top2+2,1,0);
int s=1,t=top1+top2+2;
printf("%d\n",sap(s,t));
}
return 0;
}