1. 程式人生 > >POJ 2195 Going Home(KM)

POJ 2195 Going Home(KM)

人是可以踩踏房子經過的,那距離就很好求了。建圖求距離,把距離設為負的,就轉化為KM了,最後別忘了負號。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int MAX_N = 100 + 30;
const int INF = 0x3f3f3f3f;

int n_x, n_y;//兩邊的點數
int G[MAX_N][MAX_N];//二分圖權值
int link[MAX_N], l_x[MAX_N], l_y[MAX_N];//y中各店匹配的狀態,  x,y,中的點標號
int slack[MAX_N];
bool vis_x[MAX_N], vis_y[MAX_N];

bool DFS(int x)
{
    vis_x[x] = true;
    for(int y = 0; y < n_y; y++)
    {
        if(vis_y[y])
            continue;
        int temp = l_x[x] + l_y[y] - G[x][y];
        if(temp == 0)
        {
            vis_y[y] = true;
            if(link[y] == -1 || DFS(link[y]))
            {
                link[y] = x;
                return true;
            }
        }
        else if(slack[y] > temp)
            slack[y] = temp;
    }
    return false;
}

int KM()
{
    memset(link, -1, sizeof(link));
    memset(l_y, 0, sizeof(l_y));
    for(int i = 0; i < n_x; i++)
    {
        l_x[i] = -INF;
        for(int j = 0; j < n_y; j++)
            if(G[i][j] > l_x[i])
                l_x[i] = G[i][j];
    }
    for(int x = 0; x < n_x; x++)
    {
        for(int i = 0; i < n_y; i++)
            slack[i] = INF;
        while(true)
        {
            memset(vis_x, false, sizeof(vis_x));
            memset(vis_y, false, sizeof(vis_y));
            if(DFS(x))
                break;
            int d = INF;
            for(int i = 0; i < n_y; i++)
                if(!vis_y[i] && d > slack[i])
                    d = slack[i];
            for(int i = 0; i < n_y; i++)
                if(vis_x[i])
                    l_x[i] -= d;
            for(int i = 0; i < n_y; i++)
            {
                if(vis_y[i])
                    l_y[i] += d;
                else
                    slack[i] -= d;
            }
        }
    }
    int res = 0;
    for(int i = 0; i < n_y; i++)
        if(link[i] != -1)
            res += G[link[i]][i];
    return res;

}
char _map[MAX_N][MAX_N];

struct Man
{
    int x, y;
};
struct House
{
    int x, y;
};
Man man[MAX_N];
House house[MAX_N];

int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF && n + m)
    {
        for(int i = 0; i < n; i++)
            scanf("%s", _map[i]);
        int cnt_man = 0, cnt_house = 0;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                if(_map[i][j] == 'm')
                {
                    man[cnt_man].x = i;
                    man[cnt_man++].y = j;
                }
                else if(_map[i][j] == 'H')
                {
                    house[cnt_house].x = i;
                    house[cnt_house++].y = j;
                }
            }
        }
        n_x = cnt_man;
        n_y = cnt_house;
        for(int i = 0; i < cnt_man; i++)
            for(int j = 0; j < cnt_house; j++)
                G[i][j] = -(abs(man[i].x - house[j].x) + abs(man[i].y - house[j].y));
        printf("%d\n", -KM());
    }
    return 0;
}


相關推薦

POJ-2195 Going Home---KM算法求最小權值匹配(存負邊)

for 二分圖 ostream lse ons nod esp 範圍 預處理 題目鏈接: https://vjudge.net/problem/POJ-2195 題目大意: 給定一個N*M的地圖,地圖上有若幹個man和house,且man與house的數量一致。man每移動

POJ 2195 Going Home(KM)

人是可以踩踏房子經過的,那距離就很好求了。建圖求距離,把距離設為負的,就轉化為KM了,最後別忘了負號。 #include <iostream> #include <cstring> #include <cstdio> #include

POJ 2195-Going HomeKM演算法/最小費用最大流演算法)

Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21730 Accepted: 10990 Description On a grid map there are n

POJ 2195 Going Home(最小權匹配、KM演算法)

題目連結: POJ 2195 Going Home 題意: 給出一個r*c的矩陣,字母H代表房屋,字母m代表客人,房屋的數量和客人的數量相同。每間房只能住一個人。求這些客人全部住進客房的最少移動步數? #include <cstdio>

POJ 2195 Going Home(二分圖最大權值匹配) KM

There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M

HDU 2255 奔小康賺大錢 POJ 2195 Going Home 最大權完美匹配 KM演算法

兩道KM演算法模板題 可以作為求最大完美匹配模板 一個是求最大權,一個求最小權 ,最小權可以將所有的邊權取相反數,求得最大權之後再取反。 HDU 2255程式碼: /*--------------------- #headfile--------------------*

POJ 2195 Going Home(費用流)

void 個人 nod const 移動 方向 push class main http://poj.org/problem?id=2195 題意: 在一個網格地圖上,有n個小人和n棟房子。在每個時間單位內,每個小人可以往水平方向或垂直方向上移動一步,走到相鄰的方格中。

[poj] 2195 Going Home || 最小費用最大流

etc 移動 數量 print getc truct pop namespace -c 原題 給定一個N*M的地圖,地圖上有若幹個人和房子,且人與房子的數量一致。人每移動一格需花費1(即單位費用=單位距離),一間房子只能入住一個人。現在要求所有的人都入住,求最小費用。 把每

POJ 2195 GOING HOME

容量 pac min max cpp can 超級 最短 [1] 對於每一個H 每一個m編號 然後遍歷每一個m 使用BFS求出該m到每一個H的最短距離 然後把邊加進圖裏 超級源點 超級匯點 容量為1 費用為0 跑一遍最小費用流 #include <iostream

POJ-2195 Going Home

將題目轉化為最小費用最大流問題 在每個人和房子之間建邊,容量為1,cost為兩點之間的曼哈頓距離 然後源點連向人,容量1,cost=0,房子連向匯點,容量1,cost=0 從源點到匯點跑一遍演算法就得到答案 #include<iostream> #include<c

POJ 2195 Going Home 【二分圖最小權值匹配】

傳送門:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Tota

POJ 2195 Going Home(最小費用最大流)題解

題意:給你一張圖,有k個人和k個房子,每個房子只能住一個人,每個人到某一房子的花費為曼哈頓距離,問你讓k個人怎麼走,使他們都住房子且花費最小。 思路:我們把所有人和超級源點相連,流量為1花費為0,所有房子和超級匯點相連,流量為1花費為0,然後把所有人和所有房子加邊,流量為1

POJ 2195 Going Home(網路流-費用流)

Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17777 Accepted: 9059 Description On a grid map there are n

POJ 2195 Going Home (最小費用最大流)

題目連結 第一次寫最小費用最大流 最小費用最大流相當於最短路和最大流的結合,建立了殘量圖後,費用作為距離 然後bfs遍歷源點到匯點的最小費用,用陣列記錄遍歷路徑,而後通過最大流的做法 對殘量圖進行更新,尋找路徑中的最小流量得到的就是最小費用最大流。 題

POJ 2195 Going Home(最小費用最大流)

Description: On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, ei

2195 Going Home (構圖 最大匹配KM演算法)

題意: ‘.’ ,‘m’, ‘H’-> 通路, 人, 房子 讓所有人回到房子裡,使得總路徑最小 分析: 由題意可知,人與房的距離為權值,人和房子分別為x、y兩個集合,所以可以轉換成二部圖【權值最大】匹配問題,只要把路徑取【負值】,最後結果再取負即可 構圖之後直接使用

hdu1533 Going Home km算法解決最小權完美匹配

number send hdu 所有 end man rest until 相反數 Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

2195 Going Home 【最小費用流】

題意:n*m的地圖有人和房子,要讓每個人進入一個房子(每個房子只能進入一個人,人可以走任何地方(可以經過房子也可以多 人在一個位置,每個人走一步花費1美元,求最小的花費。 思路:最小費用流模板,建好圖。。抄模板就行了,這個圖比較好建。 原點0~(1~k)房子~(k+1~

2195 Going Home (網路流最小流)

On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or ver

2195 Going Home (最小費用最大流)

Going HomeTime Limit: 1000MSMemory Limit: 65536KTotal Submissions: 24299Accepted: 12196DescriptionOn a grid map there are n little men and