POJ2195费用流+BFS建图
题意:
给你一个n*m的地图,上面有w个人,和w个房子,每个人都要进房子,每个房子只能进一个人,问所有人都进房子的路径总和最少是多少?
思路:
比较简单的最大流,直接建立两排,左边人,右边房子,广搜或者深搜求距离建图,然后一边费用流就行了,比较简单,没啥说的地方,就这样。
#include<queue>
#include<stdio.h>
#include<string.h>
#define N_node 200 + 10
#define N_edge (200 * 200 + 200 ) * 2 + 100
#define INF 1000000000
using namespace std;
typedef struct
{
int from ,to ,cost ,flow ,next;
}STAR;
typedef struct
{
int x ,y ,t;
}NODE;
STAR E[N_edge];
NODE xin ,tou;
int list[N_node] ,tot;
int s_x[N_node];
int mer[N_node];
int map[102][102] ,n ,m;
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
void add(int a ,int b ,int c ,int d)
{
E[++tot].from = a;
E[tot].to = b;
E[tot].cost = c;
E[tot].flow = d;
E[tot].next = list[a];
list[a] = tot;
E[++tot].from = b;
E[tot].to = a;
E[tot].cost = -c;
E[tot].flow = 0;
E[tot].next = list[b];
list[b] = tot;
}
bool SPFA(int s ,int t ,int n)
{
for(int i = 0 ;i <= n ;i ++)
s_x[i] = INF;
bool mark[N_node] = {0};
queue<int>q;
q.push(s);
mark[s] = 1;
s_x[s] = 0;
memset(mer ,255 ,sizeof(mer));
while(!q.empty())
{
int xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int k = list[tou] ;k ;k = E[k].next)
{
xin = E[k].to;
if(s_x[xin] > s_x[tou] + E[k].cost && E[k].flow)
{
s_x[xin] = s_x[tou] + E[k].cost;
mer[xin] = k;
if(!mark[xin])
{
mark[xin] = 1;
q.push(xin);
}
}
}
}
return mer[t] != -1;
}
int M_C_Flow(int s ,int t ,int n)
{
int mincost = 0 ,maxflow = 0 ,minflow;
while(SPFA(s ,t ,n))
{
minflow = INF;
for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])
if(minflow > E[i].flow) minflow = E[i].flow;
for(int i = mer[t] ;i + 1 ;i = mer[E[i].from])
{
E[i].flow -= minflow;
E[i^1].flow += minflow;
mincost += E[i].cost;
}
maxflow += minflow;
}
return mincost;
}
void BFS_Buid(int x ,int y ,int N)
{
xin.x = x ,xin.y = y ,xin.t = 0;
int mark[105][105] = {0};
queue<NODE>q;
mark[x][y] = 1;
q.push(xin);
while(!q.empty())
{
tou = q.front();
q.pop();
if(map[tou.x][tou.y] > N)
add(map[x][y] ,map[tou.x][tou.y] ,tou.t ,INF);
for(int i = 0 ;i < 4 ;i ++)
{
xin.x = tou.x + dir[i][0];
xin.y = tou.y + dir[i][1];
xin.t = tou.t + 1;
if(xin.x >= 1 && xin.x <= n && xin.y >= 1 && xin.y <= m && !mark[xin.x][xin.y])
{
mark[xin.x][xin.y] = 1;
q.push(xin);
}
}
}
return ;
}
int main ()
{
int i ,j;
char str[105][105];
while(~scanf("%d %d" ,&n ,&m) && n + m)
{
int M = 0 ,H = 0 ,N = 0;
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str[i]);
for(j = 0 ;j < m ;j ++)
if(str[i][j] == 'm')
N ++;
}
for(i = 1 ;i <= n ;i ++)
{
for(j = 1 ;j <= m ;j ++)
{
if(str[i][j-1] == '.') map[i][j] = 0;
else if(str[i][j-1] == 'm') map[i][j] = ++M;
else
{
++H;
map[i][j] = H + N;
}
}
}
memset(list ,0 ,sizeof(list)) ,tot = 1;
for(i = 1 ;i <= N ;i ++)
add(0 ,i ,0 ,1) ,add(i + N ,N + N + 1 ,0 ,1);
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
{
if(map[i][j] && map[i][j] <= N)
BFS_Buid(i ,j ,N);
}
printf("%d\n" ,M_C_Flow(0 ,N + N + 1 ,N + N + 1));
}
return 0;
}
POJ2195费用流+BFS建图的更多相关文章
- poj--1149--PIGS(最大流经典建图)
PIGS Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u Submit Status D ...
- 【BZOJ-2879】美食节 最小费用最大流 + 动态建图
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1366 Solved: 737[Submit][Status] ...
- BZOJ-1433 假期的宿舍 最大流+基础建图
网络流练习ing.. 1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1748 Solved: 765 [S ...
- poj 1149 PIGS【最大流经典建图】
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18727 Accepted: 8508 Description ...
- poj 3026 Borg Maze bfs建图+最小生成树
题目说从S开始,在S或者A的地方可以分裂前进. 想一想后发现就是求一颗最小生成树. 首先bfs预处理得到每两点之间的距离,我的程序用map做了一个映射,将每个点的坐标映射到1-n上,这样建图比较方便. ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
- POJ1149 最大流经典建图PIG
题意: 有一个人,他有m个猪圈,每个猪圈里都有一定数量的猪,但是他没有钥匙,然后依次来了n个顾客,每个顾客都有一些钥匙,还有他要卖猪的数量,每个顾客来的时候主人用顾客的钥匙打开相应的门,可 ...
- hdu 4568 Hunter bfs建图+TSP状压DP
想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...
- POJ 2049 Finding Nemo bfs 建图很难。。
Finding Nemo Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 6952 Accepted: 1584 Desc ...
随机推荐
- 测试平台系列(1) 搭建Flask服务
搭建Flask服务 项目地址 点我进入项目地址 代码都会在这里有所展示,喜欢的话可以帮点个star,谢谢大家了!如果你喜欢该教程,也可以分享给其他人. 关于选型 想了很久,本来打算用「Gin」做为后端 ...
- WS1008网络损伤测试仪
WS1008网络损伤测试仪具备高性能的网络损伤仿真功能.冗余链路测试功能和线速流量生成功能,提供了综合性的网络系统测试方案,可充分测试.验证网络系统的抗损伤能力.链路切换能力及数据转发能力.为高可靠性 ...
- LNMP配置——安装Nginx
一.下载 #cd /usr/local/src/ #wget http://nginx.org/download/nginx-1.16.1.tar.gz 二.解压 # tar zxf nginx-1. ...
- 使用HTML、jquery、DOM创建文本
<html> <head> <meta charset="utf-8"> <meta charset="utf-8"& ...
- CRC校验原理和verilog实现方法(一)
1.CRC简介 CRC全称循环冗余校验(Cyclic Redundancy Check, CRC),是通信领域数据传输技术中常用的检错方法,用于保证数据传输的可靠性.网上有关这方面的博客和资料很多,本 ...
- python-类的隐藏和封装
7 """ 8 封装是面对对象的三大特征之一(另外两个是集成和多态),它指的是将对象> 的信息隐藏在对象的内部,不允许外部程序直接访问对象内部信息,而是通> ...
- Android Studio 之创建自定义控件
•前言 常用控件和布局的继承结构,如下图所示: 可以看到,我们所用的所有的控件都是直接或者间接的继承自View的: 所用的所有布局都是直接或者间接继承自ViewGroup的: View 是 Andro ...
- Android学习之RecyclerView初探究
•RecyclerView基本用法 RecyclerView是新增的控件,为了让 RecyclerView 在所有 Android 版本上都能使用; Android 团队将 RecyclerView ...
- Python基础之:Python中的类
目录 简介 作用域和命名空间 class 类对象 类的实例 实例对象的属性 方法对象 类变量和实例变量 继承 私有变量 迭代器 生成器 简介 class是面向对象编程的一个非常重要的概念,python ...
- Vscode部分快捷键 Ps的简单使用 less中的除法问题 H5 四种布局
vscode 部分快捷键 ctrl+/ 注释ctrl+回车 光标下移alt+shift+上下箭头 将本行代码向上或向下复制ul>li 自动写alt ,鼠标一直点,就会有很多光标,可以一起写ctr ...