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 1087 -- A Plug for UNIX(最大流,建图)(文末有极限数据)
题目链接 Description You are in charge of setting up the press room for the inaugural meeting of the Uni ...
- POJ 3436 -- ACM Computer Factory(最大流,建图)
题目链接 Description As you know, all the computers used for ACM contests must be identical, so the part ...
- POJ1149 最大流经典建图PIG
题意: 有一个人,他有m个猪圈,每个猪圈里都有一定数量的猪,但是他没有钥匙,然后依次来了n个顾客,每个顾客都有一些钥匙,还有他要卖猪的数量,每个顾客来的时候主人用顾客的钥匙打开相应的门,可 ...
- POJ 1459 -- Power Network(最大流, 建图)
题目链接 Description A power network consists of nodes (power stations, consumers and dispatchers) conne ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
- HDU Problem - 3338 Kakuro Extension (最大流,建图)
题目链接 Problem Description If you solved problem like this, forget it.Because you need to use a comple ...
- 【POJ - 1459】Power Network(网络流最大流,建图)
题干: A power network consists of nodes (power stations, consumers and dispatchers) connected by power ...
- hdu 4568 Hunter bfs建图+TSP状压DP
想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...
- [ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)
problem luogu-P3342 solution 你感觉这道题没考什么,又感觉考了什么 通过样例以及题面,我们并未获取到『立方体每个小方块的编号是按一定规则命名』的信息. 也就是说,我们需要通 ...
最新文章
- Deepgreen Greenplum DBA小白普及课之三(备份问题解答)
- 2012年2月16日
- 为GridView添加表头thead
- [dpdk] SDK编译-简单扼要版
- Java学习 第四章 java面向对象(二)
- matlab icol,Matlab 图像处理相关函数命令大全
- mysql 备份数据
- 使用phoneGap和Sencha Touch 2开发Android应用程序(四)
- 小前端眼里的大前端:GMTC 2018 参会小结
- java 4级_《软件测试人员(Java)(4级)》【价格 目录 书评 正版】_中国图书网
- win10搭建无盘服务器配置,win10电脑搭建无盘工作站
- 斐讯k2p 月光银 硬件版本A2-软件版本22.7.8.5 刷官改系统
- 分布式机器学习——入门篇
- android系统同时使用wifi和4g上网
- Tiled map导入问题
- 【漏洞复现】CVE-2020-0796永恒之黑漏洞复现
- python代码怎么换行继续写_python代码太长怎么换行
- 《冒险者传说》召唤台在哪
- java解决跨域我呢提尼_野生狐狸被救以后,与狗狗成了好朋友,跨域种族的友情很不可思议...
- android类似于ios剪切框图片,不必羡慕 iOS,Android 上也有这些好用的截图处理工具...