题目连接:http://poj.org/problem?id=2195
题目大意 :题目的意思就是给你一个map然后m代表人,h代表house,一个人只能进入一个house,一个house只能住一个人,问你所以人进入house所能用的最小步数是多少~
思路:把man和house分别看做一个集合,这样的话你就可以对每个人和每个house 连接,cao = 1,cost = abs(x1-x2)+abs(y1-y2);然后开一个超级源点就可以了。其实模型就是走多少次就是容量。费用根据题目而定。
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 using namespace std; 9 const int maxn = 10050; 10 const int inf = 100000; 11 char str[105][105]; 12 struct node 13 { 14 int x,y; 15 }; 16 struct edge 17 { 18 int u,v,cap,flow,cost; 19 }; 20 vector<struct node>house; 21 vector<struct node>man; 22 vector<int>g[10050]; 23 vector<struct edge>e; 24 void init(int n) 25 { 26 for(int i = 0;i <= n;i++) 27 g[i].clear(); 28 e.clear(); 29 return; 30 } 31 void addedge(int u,int v,int cap,int flow,int cost) 32 { 33 e.push_back((struct edge){u,v,cap,flow,cost}); 34 e.push_back((struct edge){v,u,0,flow,-cost}); 35 int m; 36 m = e.size(); 37 g[u].push_back(m-2); 38 g[v].push_back(m-1); 39 return ; 40 } 41 int vis[maxn]; 42 int pre[maxn]; 43 int dis[maxn]; 44 int a[maxn]; 45 int spfa(int s,int t,int n,int &flow,int &cost) 46 { 47 int i,u,v; 48 for(i = 0;i <= n;i++) 49 dis[i] = inf; 50 memset(vis,0,sizeof(vis)); 51 dis[s] = pre[s] = 0; 52 a[s] = inf; 53 queue<int>q; 54 q.push(s); 55 vis[s] = 1; 56 while(!q.empty()) 57 { 58 59 u = q.front(); 60 vis[u] = 0; 61 q.pop(); 62 63 for(i = 0;i < g[u].size();i++) 64 { 65 struct edge & ei = e[g[u][i]]; 66 v = ei.v; 67 if(ei.cap > ei.flow && dis[v] > dis[u]+ei.cost) 68 { 69 dis[v] = dis[u]+ei.cost; 70 pre[v] = g[u][i]; 71 a[v] = min(a[u],ei.cap-ei.flow); 72 if(!vis[v]) 73 q.push(v),vis[v] = 1; 74 } 75 } 76 } 77 if(dis[t] == inf) 78 return 0; 79 80 flow += a[t]; 81 cost += a[t]*dis[t]; 82 83 u = t; 84 while(u != s) 85 { 86 e[pre[u]].flow += a[t]; 87 e[pre[u]^1].flow -= a[t]; 88 u = e[pre[u]].u; 89 } 90 return 1; 91 } 92 93 int mcmf(int s,int t,int n) 94 { 95 int flow = 0; 96 int cost = 0; 97 while(spfa(s,t,n,flow,cost)); 98 return cost; 99 } 100 int main() 101 { 102 int m,n,i,j; 103 while(scanf("%d %d",&n,&m)&&(m||n)) 104 { 105 for(i = 0;i < n;i++) 106 scanf("%s",str[i]); 107 house.clear(); 108 man.clear(); 109 for(i = 0;i < n;i++) 110 { 111 for(j = 0;j < m;j++) 112 { 113 if(str[i][j] == 'H') 114 house.push_back((struct node){i,j}); 115 else if(str[i][j] == 'm') 116 man.push_back((struct node){i,j}); 117 } 118 } 119 120 int hsize,msize; 121 hsize = house.size(); 122 msize = man.size(); 123 124 init(hsize+msize+5); 125 for(i = 0;i < msize;i++) 126 { 127 for(j = 0;j < hsize;j++) 128 { 129 int cost; 130 cost = abs(man[i].x-house[j].x)+abs(man[i].y-house[j].y); 131 addedge(i+1,j+msize+1,1,0,cost); 132 } 133 } 134 for(j = 0;j < man.size();j++) 135 { 136 addedge(0,j+1,1,0,0); 137 } 138 for(i = 0;i < hsize;i++) 139 addedge(msize+1+i,msize+hsize+1,1,0,0); 140 141 int ans; 142 ans = 0; 143 ans = mcmf(0,hsize+msize+1,hsize+msize+2); 144 cout<<ans<<endl; 145 } 146 return 0; 147 }