给出一个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. jQuery之Deferred对象的使用

    详见:http://www.imooc.com/code/8907 JavaScript的执行流程是分为"同步"与"异步" 传统的异步操作会在操作完成之后,使用 ...

  2. java编程之:生成rsa密钥

    通过openssl工具生成RSA的公钥和私钥(opnssl工具可在互联网中下载到,也可以点此下载无线接口包,里面包含此工具) 打开openssl文件夹下的bin文件夹,执行openssl.exe文件: ...

  3. IntelliJ IDEA 开发前的设置

    1.IntelliJ IDEA 显示行号方法 设置方法:File->Settings->Editor->General->Appearance->Show line nu ...

  4. 【转】SocketRocket:iOS WebSocket客户端开源框架

    原文网址:http://blog.csdn.net/zmp1123/article/details/44015507 WebSocket: WebSocket通信协议实现的是基于浏览器的原生socke ...

  5. MMU讲解

    MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制 ...

  6. 谓词的使用 -ios

    #import <Foundation/Foundation.h> @interface Person : NSObject<NSCopying> @property(nona ...

  7. 开发成功-cpu-mem监控动态折线图--dom esayui js java

    jsp ------------------------------------------------------------------------------------------- ---- ...

  8. CARP-VRRP-HSRP

    CARP-VRRP-HSRP http://www.openbsd.org/faq/pf/carp.html

  9. 2016国赛B题小区数据爬取软件

    -------------------------请以任何方式留言给作者,否则视为窃取----------------------------- 看你们找数据找的那么辛苦 我就苦逼的花了1个小时写了个 ...

  10. python小程序:无限求和平均

    编写一个程序,重复读取数据,直到用户输入‘done’.一旦输入‘done’,打印总和.个数与平均值.如果用户输入的不是数字,使用try和except捕获异常,打印错误信息,然后跳过继续执行循环. ar ...