POJ 2195 Going Home 最小费用流 裸题
给出一个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 最小费用流 裸题的更多相关文章
- POJ 3068 运送危险化学品 最小费用流 模板题
"Shortest" pair of paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1215 ...
- poj 1201 Intervals——差分约束裸题
题目:http://poj.org/problem?id=1201 差分约束裸套路:前缀和 本题可以不把源点向每个点连一条0的边,可以直接把0点作为源点.这样会快许多! 可能是因为 i-1 向 i 都 ...
- POJ 2195 Going Home 最小费用流
POJ2195 裸的最小费用流,当然也可以用KM算法解决,但是比较难写. 注意反向边的距离为正向边的相反数(因此要用SPFA) #include<iostream> #include< ...
- POJ 1469 ZOJ1140 二分匹配裸题
很裸,左点阵n,右点阵m 问最大匹配是否为n #include <cstdio> #include <cstring> #include <vector> usin ...
- POJ 2195 Going Home 最小费用流 难度:1
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17955 Accepted: 9145 Descr ...
- poj 2407 欧拉函数裸题
http://poj.org/problem?id=2407 题意:多组数据,每次输入一个数 ,求这个数的欧拉函数 int euler_phi(int n){//单个欧拉函数 int m=(int)s ...
- POJ 3461 Oulipo(KMP裸题)
Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...
- POJ 1287 Networking(最小生成树裸题有重边)
Description You are assigned to design network connections between certain points in a wide area. Yo ...
- 主席树----POJ 2104(主席树裸题)(转)
首先来介绍一下我们需求:给你n个数,多次问你某个区间内的第k小是哪个数 主席树: 主席树的全名应该是 函数式版本的线段树.加上附带的一堆 technology.. ..总之由于原名字太长了,而且 “主 ...
随机推荐
- backtrack下whatweb的使用
whatweb是backtrack下的一款Web识别工具,位于 Applications-->BackTrack-->Information Gathing-->Web Applic ...
- C++ 实用的小程序
1. 打开test_ids.txt 将里面的东西添加"1_",然后另存为test_ids_repaired.txt #include <iostream> #inclu ...
- fasterflect-vs-hyperdescriptor-vs-fastmember-vs-reflection/
http://www.codewrecks.com/blog/index.php/2008/10/04/expression-tree-vs-reflection/ http://www.codepr ...
- jquery获取高度错误(可以获取到宽度,但获取不到高度),及解决办法
<div class="foo"> <div style="display: none;"> 3333333 </div> ...
- HTTP头详解
HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Chars ...
- CSRF(Cross-site request forgery)跨站请求伪造
CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一.其他安全隐患,比如 ...
- SQL Server 表所在的文件组
SELECT o.[name] ,-- o.[type], i.[name], i.[index_id], f.[name] FROM sys.indexes i ...
- asp.net脚本获取不到id,服务器控件id生成html页面id控制
在配置文件里修改id的生成方式.经过搜索发现是因为使用Sharpmap而在Web.config中加入的一句配置造成的影响. <pages controlRenderingCompatibilit ...
- 解决windows系统80端口被占用问题
在windows下部署web应用(80端口),启动时提示bind 80端口失败 检查端口占用: netstat -ano | findstr 发现System进程 (pid=4) 占用了端口 然而本机 ...
- python_Day1_基础知识开篇
一.python安装 1)windows上同时安装python2.0和python3.0配置 (1)在python官网下载windows版本python2.0和python3.0安装包 官网地址:ht ...