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 Home(KM演算法/最小費用最大流演算法)
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