POJ 2195 Going Home 费用流 最小费用流

题目连接: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 }

 

posted @ 2013-03-27 13:38  某某。  阅读(258)  评论(0编辑  收藏  举报