http://acm.hdu.edu.cn/showproblem.php?pid=1533
这道题直接用了模板
题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用
要注意void init(int n) 这个函数一定要写
一开始忘记写这个WA了好几发
还有这个题很容易T掉,赋值建图要简化,一开始构建成网络流那种图一直T
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> #define oo 0x13131313 using namespace std; const int INF = 0x3f3f3f3f; const int MAXN=400; const int MAXM=200000; struct Edge { int to,next,cap,flow,cost; } edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N; void init(int n) { N = n; tol = 0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } bool spfa(int s,int t) { queue<int>q; 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 minCostMaxflow(int s,int t,int &cost) { int flow = 0; cost = 0; 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; } return flow; } struct Home { int x,y; } H[MAXN],P[MAXN]; int main() { int totH,totP; int NN,MM; while(cin>>NN>>MM&&NN&&MM) { getchar(); init(MAXN); char c; totH=0; totP=0; for(int i=1; i<=NN; i++) { for(int j=1; j<=MM; j++) { scanf("%c",&c); if(c=='H') totH++,H[totH].x=i,H[totH].y=j; else if(c=='m') totP++,P[totP].x=i,P[totP].y=j; } getchar(); } int ANS=0; int NNN=totP+totH; for(int i=1; i<=totP; i++) for(int j=1; j<=totH; j++) { int t=abs(P[i].x-H[j].x)+abs(P[i].y-H[j].y); addedge(i,j+totP,1,t); } for(int i=1; i<=totP; i++) addedge(NNN+1,i,1,0); for(int i=totP+1; i<=NNN; i++) addedge(i,NNN+2,1,0); minCostMaxflow(NNN+1,NNN+2,ANS); printf("%d ",ANS); } return 0; }