给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数。

现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人。

每个人可以向4个方向移动,每移动一步需要1$,问所有人移动到房子里的最少花费。

其中,n,m<=100,最多有100个人。

最小给用流裸题。

建立一个超级源点,跟每一个房子连一条边,容量为1,花费为0

每一个人与超级汇点连一条边,容量为1,花费为0

一个房子与每一个人建一条边,房子指向人,容量为1,花费用2者的距离(不是直线距离)

然后跑最小费用流算法就可以了。

 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue> using namespace std; const int maxn=;
const int inf=0x3f3f3f3f;
const int s=;
int t;
int tot;
char maze[maxn];
char str[maxn][maxn];
bool vis[maxn];
int dis[maxn];
int prev[maxn];
int pree[maxn]; struct Point
{
int x,y;
};
Point point[maxn];
struct Edge
{
int to,cap,cost,rev;
};
vector<Edge>edge[maxn]; inline int get_abs(int tmp)
{
if(tmp>)
return tmp;
return -tmp;
} inline int min(int x,int y)
{
return x<y?x:y;
} inline int get_dis(int i,int j)
{
return get_abs(point[i].x-point[j].x)+get_abs(point[i].y-point[j].y);
} void addedge(int from,int to,int cap,int cost)
{
edge[from].push_back((Edge){to,cap,cost,edge[to].size()});
edge[to].push_back((Edge){from,,-cost,edge[from].size()-});
} void build_graph(int n,int m)
{
//要从0开始
for(int i=;i<maxn;i++)
edge[i].clear();
tot=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(str[i][j]=='H')
{
point[tot].x=i;
point[tot++].y=j;
}
}
}
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(str[i][j]=='m')
{
point[tot].x=i;
point[tot++].y=j;
}
}
}
t=tot;
tot--;
tot/=;
for(int i=;i<=tot;i++)
{
addedge(s,i,,);
addedge(i+tot,t,,);
}
for(int i=;i<=tot;i++)
{
for(int j=tot+;j<=tot*;j++)
{
addedge(i,j,,get_dis(i,j));
}
}
} void spfa()
{
memset(vis,false,sizeof vis);
for(int i=;i<=t;i++)
dis[i]=inf;
queue<int>que;
while(!que.empty())
que.pop();
que.push(s);
dis[s]=;
vis[s]=true;
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=false; //要记得这步
for(int i=;i<edge[u].size();i++)
{
Edge &e=edge[u][i];
if(e.cap>&&dis[e.to]>dis[u]+e.cost)
{
dis[e.to]=dis[u]+e.cost;
prev[e.to]=u;
pree[e.to]=i;
if(!vis[e.to])
{
vis[e.to]=true;
que.push(e.to);
}
}
}
}
return ;
} int solve()
{
int ret=;
int flow=tot;
while(flow>)
{
spfa();
int f=flow;
for(int i=t;i!=s;i=prev[i])
{
f=min(f,edge[prev[i]][pree[i]].cap);
}
flow-=f;
ret+=dis[t]*f;
for(int i=t;i!=s;i=prev[i])
{
Edge &e=edge[prev[i]][pree[i]];
e.cap-=f;
edge[e.to][e.rev].cap+=f;
}
}
return ret;
} int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m)
break;
for(int i=;i<=n;i++)
{
scanf("%s",str[i]+);
}
build_graph(n,m);
printf("%d\n",solve());
}
return ;
}

POJ 2195 Going Home 最小费用流 裸题的更多相关文章

  1. POJ 3068 运送危险化学品 最小费用流 模板题

    "Shortest" pair of paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1215 ...

  2. poj 1201 Intervals——差分约束裸题

    题目:http://poj.org/problem?id=1201 差分约束裸套路:前缀和 本题可以不把源点向每个点连一条0的边,可以直接把0点作为源点.这样会快许多! 可能是因为 i-1 向 i 都 ...

  3. POJ 2195 Going Home 最小费用流

    POJ2195 裸的最小费用流,当然也可以用KM算法解决,但是比较难写. 注意反向边的距离为正向边的相反数(因此要用SPFA) #include<iostream> #include< ...

  4. POJ 1469 ZOJ1140 二分匹配裸题

    很裸,左点阵n,右点阵m 问最大匹配是否为n #include <cstdio> #include <cstring> #include <vector> usin ...

  5. POJ 2195 Going Home 最小费用流 难度:1

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17955   Accepted: 9145 Descr ...

  6. poj 2407 欧拉函数裸题

    http://poj.org/problem?id=2407 题意:多组数据,每次输入一个数 ,求这个数的欧拉函数 int euler_phi(int n){//单个欧拉函数 int m=(int)s ...

  7. POJ 3461 Oulipo(KMP裸题)

    Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...

  8. POJ 1287 Networking(最小生成树裸题有重边)

    Description You are assigned to design network connections between certain points in a wide area. Yo ...

  9. 主席树----POJ 2104(主席树裸题)(转)

    首先来介绍一下我们需求:给你n个数,多次问你某个区间内的第k小是哪个数 主席树: 主席树的全名应该是 函数式版本的线段树.加上附带的一堆 technology.. ..总之由于原名字太长了,而且 “主 ...

随机推荐

  1. STL概述

    一.关于STL STL(Standard Template Library,标准模板库)是C++语言标准中的重要组成部分.STL 以模板类和模板函数的形式为程序员提供了各种数据结构和算法的精巧实现,程 ...

  2. hadoop常用管理员命令

    hadoop job -list 列出正在运行的job hadoop job -kill kill掉job hadoop fsck 检查HDFS坏快 hadoop dfsadmin -report检查 ...

  3. JS构造函数详解

    //构造函数 //使自己的对象多次复制,同时实例根据设置的访问等级可以访问其内部的属性和方法 //当对象被实例化后,构造函数会立即执行它所包含的任何代码 function myObject(msg) ...

  4. 黑马程序员——JAVA基础之程序控制流结构之判断结构,选择结构

    ------- android培训.java培训.期待与您交流! ---------- 程序控制流结构:顺序结构:判断结构:选择结构:循环结构. 判断结构:条件表达式无论写成什么样子,只看最终的结构是 ...

  5. awesome-nlp

    awesome-nlp  A curated list of resources dedicated to Natural Language Processing Maintainers - Keon ...

  6. 多网卡 指定网卡到指定IP

    route add -net 1.2.3.0/24 gw 网关 route add -host 目标IP dev eth1route add -host 目标IP gw 网关

  7. Unity3D研究院之Android同步方法读取streamingAssets

    版本Unity5.3.3 Android 小米pad1 首先非常感谢 @守着阳光 同学在下面的留言.让我解决了一个大的谜团.. 开始我知道 StreamingAssets 路径是这个 path = & ...

  8. mysql+mybatis 插入可递增字段库表操作

    mysql本身类型介绍: BIGINT 8 字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 70 ...

  9. 如何用ABBYY把PDF转换成PPT

    在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中 ...

  10. php面向对象中的魔术方法中文说明

    1.__construct() 实例化对象是被自动调用.当__construct和以类名为函数名的函数 同时存在时调用__construct,另一个不背调用. 类名为函数名的函数为老版的构造函数. 2 ...