pku2195
来源:互联网 发布:iPhone如何传照片到Mac 编辑:程序博客网 时间:2024/06/08 17:47
/*
* File: main.cpp
* Author: chenjiang
*最小费用最大流,直接套模版
* Created on 2010年4月23日, 下午9:17
*/
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define _max 300
#define inf 314748364
int mapmap[_max][_max], cost[_max][_max], n, m;
int flow[_max][_max], min_flow[_max];
int house_index, people_index;
int N, source, sink; //图的顶点数 超级源点 超级汇点
int dist[_max], pre[_max];
int sum_cost, sum_flow;
struct House {
int x, y;
} house[_max];
struct People {
int x, y;
} people[_max];
bool visited[_max];
int MIN(int a, int b) {
if (a <= b)return a;
else
return b;
}
bool SPFA() {
int i, j, k;
memset(visited, 0, sizeof (visited));
memset(pre, -1, sizeof (pre));
queue<int> Q;
for (i = source; i <= sink; i++) {
dist[i] = inf;
}
dist[source] = 0;
Q.push(source);
visited[source] = 1;
min_flow[source] = inf;
while (!Q.empty()) {
k = Q.front();
Q.pop();
visited[k] = 0;
for (i = source; i <= sink; i++) {
if ((mapmap[k][i] - flow[k][i] > 0) && (dist[k] + cost[k][i] < dist[i])) {
dist[i] = dist[k] + cost[k][i];
if (!visited[i]) {
Q.push(i);
visited[i] = 1;
}
pre[i] = k;
min_flow[i] = MIN(min_flow[k], (mapmap[k][i] - flow[k][i]));
}
}
}
if (pre[sink] != -1)return 1;
else return 0;
}
void mincost_maxflow() {
sum_cost = 0, sum_flow = 0;
memset(flow, 0, sizeof (flow));
while (SPFA()) {
int k = sink;
while (k >= 0) {
flow[pre[k]][k] += min_flow[sink];
flow[k][pre[k]] = -flow[pre[k]][k];
k = pre[k];
}
sum_cost += dist[sink];
sum_flow += min_flow[sink];
}
}
/*
*
*/
int main(int argc, char** argv) {
int i, j, k;
char ch[105][105];
//freopen("a.a", "r", stdin);
while (cin >> n >> m) {
if (n == 0 && m == 0)break;
house_index = people_index = 0;
for (i = 0; i < n; i++) {
cin >> ch[i];
for (j = 0; j < m; j++) {
if (ch[i][j] == 'H')//当前点有一座房子,增加房子
{
house_index++; //房子的个数加1
house[house_index].x = i; //保存房子的行坐标
house[house_index].y = j; //保存房子的列坐标
} else if (ch[i][j] == 'm')//当前点是个人,增加人
{
people_index++; //人的个数加1
people[people_index].x = i; //保存人的行坐标
people[people_index].y = j; //保存人的列坐标
}
}
}
memset(mapmap, 0, sizeof (mapmap));
memset(cost, 0, sizeof (cost));
source = 0; //超级源点为0
sink = house_index + people_index + 1; //超级汇点
N = sink + 1; //图的顶点个数
for (i = 1; i <= house_index; i++) {
for (j = 1; j <= people_index; j++) {
//房子i到人j的费用
cost[i][j + house_index] = abs(house[i].x - people[j].x) + abs(house[i].y - people[j].y);
cost[j + house_index][i] = -cost[i][j + house_index]; //人j到房子i的费用
mapmap[i][j + house_index] = 1; //房子和人之间连一条边
}
}
for (i = 1; i <= house_index; i++) {
mapmap[source][i] = 1;
}
for (i = 1; i <= people_index; i++) {
mapmap[house_index + i][sink] = 1;
}
mincost_maxflow();
cout << sum_cost << endl;
}
return (EXIT_SUCCESS);
}
- pku2195
- HDU1533/PKU2195 二分图匹配 费用流
- pku2195二分图的最佳匹配问题mub
- 电脑CMD 命令操作
- SSH 配置
- 程序员能力矩阵 你属于哪一层?
- paypai 接口使用
- 触发器使用示例
- pku2195
- iPhone开发进阶(8)— 检测屏幕触摸事件
- sql 语句使用
- 我对servlet的理解(应届生乱写)
- 特殊字符处理
- 从这里开始飞吧
- iPhone开发进阶(9)— 用SQLite管理数据库
- 在Unity2.0中配置Interception Behavior实现AOP
- Tokyo Cabinet TCHDB源码阅读——tchdbnew、tchdbopen及相关函数代码