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
尼玛心累啊,为什么从源点链接房子,在链接人在链接会点jiu不行,,,,,,必须按照源点---》ren---》房子,,,,会点的顺序建图
还有数组额外注意,
尼玛了,因为数组开小,wa了14个小时,,,,,
#include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<vector> #include<map> #include<algorithm> #include<queue> using namespace std; const int maxn=10005; const int maxm=20505; const int inf=0x3f3f3f3f; struct Edge{ int to; int next; int cap,flow,cost; }edge[maxm]; int head[maxn],tot; int pre[maxn],dis[maxn]; bool vis[maxn]; int n; char str[500]; struct node{ int x,y; }p[maxn],q[maxn]; void init(int nn){ n=nn; tot=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost){ edge[tot].to=v; edge[tot].cap=cap; edge[tot].cost=cost; edge[tot].flow=0; edge[tot].next=head[u]; head[u]=tot++; edge[tot].to=u; edge[tot].cap=0; edge[tot].cost=-cost; edge[tot].flow=0; edge[tot].next=head[v]; head[v]=tot++; } bool spfa(int s,int t){ queue<int >q; // printf("n====%d\n",n); for(int i=0;i<=n;i++){ dis[i]=inf; vis[i]=false; pre[i]=-1; } dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){ dis[v]=dis[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=true; q.push(v); } } } } if(pre[t]==-1) return false; else return true; } int mincost(int s,int t,int &cost){ int flow=0; cost=0; // printf("%d\n",head[2]); while(spfa(s,t)){ int Min=inf; for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){ if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; } for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){ edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } flow+=Min; } // printf("cost=====%d flow======%d\n",cost,flow); return flow; } int main(){ int x,y; while(scanf("%d%d",&x,&y)!=EOF){ if(x==0&&y==0) break; n=x*y+1; init(n); int start=0; int end=n; int pp=0,qq=0; for(int i=1;i<=x;i++){ scanf("%s",str+1); for(int j=1;j<=y;j++){ int cnt=(i-1)*y+j; if(str[j]=='m'){ addedge(start,cnt,1,0); p[pp].x=i; p[pp++].y=j; } if(str[j]=='H'){ addedge(cnt,end,1,0); q[qq].x=i; q[qq++].y=j; } } // printf("%s\n",str+1); } for(int i=0;i<pp;i++){ for(int j=0;j<qq;j++){ addedge((p[i].x-1)*y+p[i].y,(q[j].x-1)*y+q[j].y,1,abs(p[i].x-q[j].x)+abs(p[i].y-q[j].y)); } } int tmp; int ans=mincost(start,end,tmp); printf("%d\n",tmp); } return 0; }