题意:

      给你一个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建图的更多相关文章

  1. poj--1149--PIGS(最大流经典建图)

    PIGS Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Submit Status D ...

  2. 【BZOJ-2879】美食节 最小费用最大流 + 动态建图

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1366  Solved: 737[Submit][Status] ...

  3. BZOJ-1433 假期的宿舍 最大流+基础建图

    网络流练习ing.. 1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1748 Solved: 765 [S ...

  4. poj 1149 PIGS【最大流经典建图】

    PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18727   Accepted: 8508 Description ...

  5. poj 3026 Borg Maze bfs建图+最小生成树

    题目说从S开始,在S或者A的地方可以分裂前进. 想一想后发现就是求一颗最小生成树. 首先bfs预处理得到每两点之间的距离,我的程序用map做了一个映射,将每个点的坐标映射到1-n上,这样建图比较方便. ...

  6. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  7. POJ1149 最大流经典建图PIG

    题意:       有一个人,他有m个猪圈,每个猪圈里都有一定数量的猪,但是他没有钥匙,然后依次来了n个顾客,每个顾客都有一些钥匙,还有他要卖猪的数量,每个顾客来的时候主人用顾客的钥匙打开相应的门,可 ...

  8. hdu 4568 Hunter bfs建图+TSP状压DP

    想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...

  9. POJ 2049 Finding Nemo bfs 建图很难。。

    Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 6952   Accepted: 1584 Desc ...

随机推荐

  1. 【python+selenium的web自动化】- Selenium WebDriver原理及安装

    简单介绍 selenium ​ selenium是一个用于测试web网页的自动化测试工具,它直接运行在浏览器中,模拟用户的操作.

  2. 趣谈 DHCP 协议,有点意思。

    计算机网络我也连载了很多篇了,大家可以在我的公众号「程序员cxuan」 或者我的 github 系统学习. 计算机网络第一篇,聊一聊网络基础 :计算机网络基础知识总结 计算机网络第二篇,聊一聊 TCP ...

  3. python文件操作以及循环小结

    Python中的文件使用建议使用 with open(filename, "r") as f: 的形式进行文件操作,如果忘记关闭文件指针的话,他会帮你自己关闭文件, 如果使用原来的 ...

  4. Redis之数据类型和持久化及高可用

    数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) String是r ...

  5. logging日志的使用和设置过期自动删除

    一.logging的基础使用 1.logging的级别 import logging logging.debug('debug message') # 计算或者工作的细节 logging.info(' ...

  6. Java并发编程之并发关键字

    volatile 保证可见性 一个线程修改volatile变量的值时,该变量的新值会立即刷新到主内存中,这个新值对其他线程来说是立即可见的 一个线程读取volatile变量的值时,该变量在本地内存中缓 ...

  7. od快捷键

    视图.查看相关: Alt+l  记录 Alt+e 可执行模块 Alt+m 内存 Alt+c cpu(反汇编视图) Ctrl+p 补丁 Alt+k 调用堆栈 Alt+b 断点 Alt+f5 设置窗口总在 ...

  8. Git标签与别名

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  9. SqlServer触发器的创建与使用

    前言 上期我们介绍了SqlServer的视图和存储过程创建与使用,这期我们介绍一下触发器. 有需要回顾的可以电梯直达看一下: SqlServer视图的创建与使用 SqlServer存储过程的创建与使用 ...

  10. 全网最详细的Linux命令系列-ls命令

    Linux开始必须要会的命令当属ls,在日常工作中用到ls命令时的频率是很多的,作为一个初学者,可能我只会或者顶多ls -l两种用法.但是ls其实是一个非常实用的指令,ls命令就是list的缩写,ls ...