给出一个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. OnItemSelectedListener事件与二级联动

    一.界面 1.新建province.xml件. 在“res/values”位置新建province.xml文件. (1)province.xml文件位置如下图所示: (2)province.xml内容 ...

  2. PC端的混合应用通讯问题

    exe使用C#开发,内嵌HTML页面HTML页面与exe程序的通讯方式可以使用以下方式: HTML通知exe:C#有个titlechange事件,可以监听内部HTML的title,那么HTML就可以通 ...

  3. jQuery 屏蔽鼠标快速经过

    <script type="text/javascript">    $(".Banner ul li").bind('mouseover', fu ...

  4. 免费web api接口大全

    下面的接口来自互联网,部分功能需要付费 查询手机 http://www.yodao.com/smartresult-xml/search.s?type=mobile&q=手机号码 查询IP h ...

  5. shell中[[]]和[]的主要区别

    [ ] 实际上是bash 中 test 命令的简写.即所有的 [ expr ] 等于 test expr 对 test 命令来说, 用 -eq 要进行数字比较,而你此时传入字符串,就报错了. [[ e ...

  6. SQL Server中数据库文件的存放方式,文件和文件组

    原文地址:http://www.cnblogs.com/CareySon/archive/2011/12/26/2301597.html   SQL Server中数据库文件的存放方式,文件和文件组 ...

  7. 008. asp.net mvc3.0安装文件及其安装时发生错误的解决方案

    0. 安装步骤: vs2010 → vs2010sp1→ AspNetMVC3Setup.exe→ AspNetMVC3Setup_CHS.exe→ AspNetMVC3ToolsUpdateSetu ...

  8. 虚拟化之lxc

    LXC 中文名称就是 Linux 容器工具,容器可以提供轻量级的虚拟化,以便隔离进程和资源,使用 LXC 的优点就是不需要安装太多的软件包,使用过程也不会占用太多的资源,本文循序渐进地介绍LXC的建立 ...

  9. yii 获取当前ip 常用的调用变量

    echo Yii::app()->request->hostInfo; //除域名外的URL echo Yii::app()->request->getUrl(); //除域名 ...

  10. lambda 的使用汇总

    d=lambda x:x+1print(d(10))lambda 相当于一个轻量函数返回 d=lambda x:x+1 if x>0 else "error"print(d( ...