标签:des style c class blog code
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 17230 | Accepted: 8781 |
Description
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
5 5 HH..m ..... ..... ..... mm..H
对于一个图
m代表人H代表房间
现在需要用最少的步数将所有的人送回房间,问最小步数是多少,每个房间只能容纳一个人
分析:
每个人到每个房间的花费我们可以求出来
现在,我们把人和花费都抽象成一个一个的点,将人和房间连一条花费为步数的边
那么求出最小费用最大流即可
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <cmath> 6 #include <queue> 7 using namespace std; 8 9 const int maxn = 1005; 10 11 typedef pair<int, int> PII; 12 13 char a[maxn][maxn]; 14 vector<PII>v[2]; 15 const int INF = 1000000000; 16 17 struct Edge { 18 int from, to, cap, flow, cost; 19 }; 20 21 struct MCMF 22 { 23 int n, m, s, t; 24 vector<Edge> edges; 25 vector<int> G[maxn]; 26 27 int inq[maxn]; 28 int d[maxn]; 29 int p[maxn]; 30 int a[maxn]; 31 32 void init(int n) { 33 this -> n = n; 34 for(int i = 0; i < n; i++) G[i].clear(); 35 edges.clear(); 36 } 37 38 void AddEdge(int from, int to, int cap, int cost) { 39 edges.push_back((Edge) { from, to, cap, 0, cost } ); 40 edges.push_back((Edge) { to, from, 0, 0, -cost } ); 41 m = edges.size(); 42 G[from].push_back(m - 2); 43 G[to].push_back(m - 1); 44 } 45 46 bool BellmanFord(int s, int t, int &flow, int &cost) { 47 for(int i = 0; i < n; i++) d[i] = INF; 48 memset(inq, 0, sizeof(inq) ); 49 d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF; 50 queue<int> Q; 51 Q.push(s); 52 while(!Q.empty()) { 53 int u = Q.front(); Q.pop(); 54 inq[u] = 0; 55 for(int i = 0; i < G[u].size(); i++) { 56 Edge &e = edges[G[u][i]]; 57 if(e.cap > e.flow && d[e.to] > d[u] + e.cost) { 58 d[e.to] = d[u] + e.cost; 59 p[e.to] = G[u][i]; 60 a[e.to] = min(a[u], e.cap - e.flow); 61 if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; } 62 } 63 } 64 } 65 66 if(d[t] == INF) return false; 67 flow += a[t]; 68 cost += d[t] * a[t]; 69 int u = t; 70 while(u != s) { 71 edges[p[u]].flow += a[t]; 72 edges[p[u] ^ 1].flow -= a[t]; 73 u = edges[p[u]].from; 74 } 75 return true; 76 } 77 78 int MinCost(int s, int t) { 79 //this -> s = s; this -> t = t; 80 int flow = 0, cost = 0; 81 while(BellmanFord(s, t, flow, cost)){}; 82 return cost; 83 } 84 }; 85 86 MCMF g; 87 88 int get_dist(PII p1, PII p2) { 89 return fabs(p1.first - p2.first) + fabs(p1.second - p2.second); 90 } 91 92 int main() { 93 int n, m; 94 //freopen("a.txt","r",stdin); 95 while(scanf("%d %d",&n, &m)) { 96 if(n == 0 && m == 0) 97 break; 98 //puts("*"); 99 int m_num = 0, H_num = 0; 100 for(int i = 0; i < 2; i++) { 101 v[i].clear(); 102 } 103 g.init(n * m);//节点个数 尽量大一点 104 for(int i = 0; i < n; i++) { 105 for(int j = 0; j < m; j++) { 106 scanf("\n%c",&a[i][j]);// 107 if(a[i][j] == ‘m‘) { 108 m_num++; 109 v[0].push_back(make_pair(i, j));//用vector把所有的人和房间都储存下来 110 } 111 else if(a[i][j] == ‘H‘) { 112 H_num++; 113 v[1].push_back(make_pair(i, j)); 114 } 115 } 116 } 117 int s = 0; int t = m_num + H_num + 1; 118 //printf("%d %d %d %d\n",m_num, H_num, v[0].size(), v[1].size()); 119 for(int i = 1; i <= m_num; i++) { 120 g.AddEdge(s, i, 1, 0);//源点跟人的容量为1 花费为 0 因为 只能输送一个人 121 } 122 for(int i = m_num + 1; i <= m_num + H_num; i++) { 123 g.AddEdge(i, t, 1, 0);//同理 124 } 125 126 for(int i = 0; i < v[0].size(); i++) { 127 for(int j = 0; j < v[1].size(); j++) { 128 g.AddEdge(i + 1, m_num + j + 1, 1, get_dist(v[0][i], v[1][j]));//容量为1 花费为步数 129 } 130 } 131 printf("%d\n",g.MinCost(s, t)) ; 132 } 133 return 0; 134 }
hdu2195Going Home【最小费用最大流】,布布扣,bubuko.com
标签:des style c class blog code
原文地址:http://www.cnblogs.com/zhanzhao/p/3754897.html