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 ...
随机推荐
- Gym100923H Por Costel and the Match
题目链接:http://codeforces.com/gym/100923/problem/H 分析:并查集,用enemy储存x的敌人,用weight储存权重决定根节点 需用scanf和puts输入输 ...
- 【python+selenium的web自动化】- 元素的常用操作详解(一)
如果想从头学起selenium,可以去看看这个系列的文章哦! https://www.cnblogs.com/miki-peng/category/1942527.html 本篇主要内容:1.元素 ...
- 第七届蓝桥杯省赛JavaB组——第十题压缩变换
题目: 压缩变换小明最近在研究压缩算法.他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比.然而,要使数值很小是一个挑战.最近,小明需要压缩一些正整数的序列,这些序列的特点是,后面 ...
- BZOJ_1503 [NOI2004]郁闷的出纳员 【Splay树】
一 题面 [NOI2004]郁闷的出纳员 二 分析 模板题. 对于全部员工的涨工资和跌工资,可以设一个变量存储起来,然后在进行删除时,利用伸展树能把结点旋转到根的特性,能够很方便的删除那些不符合值的点 ...
- Ajax数据爬取--爬取微博
Ajax Ajax,即异步的JaveScript和XML.它不是一门编程语言,而是利用JaveScript在保证页面不被刷新,页面链接不改变的情况下与服务器交换数据并更新部分网页的技术. 对于传统的网 ...
- HDU(1420)Prepared for New Acmer(JAVA语言)【快速幂模板】
思路:快速幂裸题. //注意用long,否则会超范围 Problem Description 集训进行了将近2个礼拜,这段时间以恢复性训练为主,我一直在密切关注大家的训练情况,目前为止,对大家的表现相 ...
- 基于开源的GOCW和Directshow.net,实现摄像头预览、采集、录像等操作
本文基于开源的GOCW和Directshow.net,实现图像采集等操作.最为关键的部分在于可以实现摄像头的控制,同时关于视频采集进行了实现. 具体的内容请关注首发于51CTO的课程<基于Csh ...
- 「HTML+CSS」--自定义按钮样式【003】
前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...
- 如何开发一个APP——转自知乎
作者:简单点链接:https://www.zhihu.com/question/22999185/answer/155469014来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- day-03-基础数据类型
基础数类型总览 10203 123 3340 int +- * / 等等 '今天吃了没?' str 存储少量的数据,+ *int 切片, 其他操作方法 True False bool 判断真假 [12 ...