1. 程式人生 > >HDU 1045 Fire Net (二分圖的最大匹配)

HDU 1045 Fire Net (二分圖的最大匹配)

/*
  構圖:對於任意一行,如果該行裡的格子彼此可到達(沒有障礙物),則把他們歸為同一個
  點,縱向也是如此。 構造出來的橫向點和縱向點,如果彼此覆蓋,則連一條邊,最後直接
  求最大匹配。
  15MS	312K
  */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define SIZE 88

using namespace std;

int N,ans;
char map[8][8];
bool cnt[SIZE][SIZE],vis[SIZE];
int link[SIZE];
int col[8][8],row[8][8];
int cc,rr;

bool dfs(int lt)
{
    for(int r=1; r<=cc; r++)
    {
        if(cnt[lt][r] && !vis[r])
        {
            vis[r] = true;
            if(link[r] == -1 || dfs(link[r]))
            {
                link[r] = lt;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    while(~scanf("%d",&N) && N)
    {
        for(int i=1; i<=N; i++)
        {
            for(int j=1; j<=N; j++)
            {
                cin >> map[i][j];
                col[i][j] = row[i][j] = 0;
            }
        }
        cc = rr = ans = 0;
        memset(cnt,0,sizeof(cnt));
        memset(link,-1,sizeof(link));
        for(int i=1; i<=N; i++)
        {
            for(int j=1; j<=N; j++)
            {
                if(map[i][j] == 'X')
                    continue;
                if(col[i][j] == 0)
                {
                    col[i][j] = ++cc;
                    int t = i + 1;
                    while(t <= N)
                    {
                        if(map[t][j] == 'X')
                            break;
                        col[t][j] = cc;
                        t ++;
                    }
                }
                if(row[i][j] == 0)
                {
                    row[i][j] = ++rr;
                    int t = j + 1;
                    while(t <= N)
                    {
                        if(map[i][t] == 'X')
                            break;
                        row[i][t] = rr;
                        t ++;
                    }
                }
            }
        }
        for(int i=1; i<=N; i++)
        {
            for(int j=1; j<=N; j++)
            {
                cnt[row[i][j]][col[i][j]] = true;
            }
        }
        for(int i=1; i<=rr; i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i))
                ans ++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


相關推薦

HDU 1045 Fire Net 二分匹配

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piec

HDU1045 Fire Net —— 二分匹配

tin pict 直接 sed esc tom 一行 resp logs 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others

HDU 1045 Fire Net (二分匹配)

/* 構圖:對於任意一行,如果該行裡的格子彼此可到達(沒有障礙物),則把他們歸為同一個 點,縱向也是如此。 構造出來的橫向點和縱向點,如果彼此覆蓋,則連一條邊,最後直接 求最大匹配。 15MS 312K */ #include <iostream&g

HDU 1045 Fire Net 二分

HDU 1045 題意:   在一個n*n地圖中,有許多可以擋住子彈的牆,問最多可以放幾個炮臺,是的炮臺不會相互損害。炮臺會向四面發射子彈。 思路:   把行列分開做,先處理行,把同一行中相互聯通的點縮成一個點。再處理列,同樣縮成一個點。然後把行列中,交點不是牆的點連一條邊。對這個圖跑網路流或者二分圖

HDU 1045 Fire Net 二分Bipartite題解

本題可以使用DFS直接爆搜出答案,不過這樣型別的題目其實是個二分圖的題解。 這個二分圖,難不在Hungary演算法,而是難在於建圖。需要挺高的抽象思維的。 建圖: 1 把同一行不被X分開的格子標同一個號碼,被X分開的標下一個號碼,這樣做是為了縮點,不需要把所有的格子都分開標

HDU 1281 - 棋盤遊戲 - [二分匹配]

鏈接 ems 枚舉 一個 輸入 string ima () have 題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1281 Time Limit: 2000/1000 MS (Java/Others) Memor

HDU 1045 Fire Net二分匹配

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

HDU 2444 (判斷二分+二分匹配)

題目連結 題意:首先判斷這個圖是否是二分圖,如果不是二分圖就輸出no,如果是二分圖就輸出最大匹配數 判斷二分圖可以用染色法。。bfs一次就可以 求二分圖最大匹配我用的匈牙利 #include<stdio.h> #include<iostream> #inclu

HDU 1528 二分匹配

題目與之前做過的一道題目(田忌賽馬hdu 1052)類似,變化不大;大意是:52張牌隨機分成數量相等的兩部分,已知玩家1的牌的排列順序 ,現在玩家2需要對自己的牌排序,使同一順序下對應的牌,自己的大,這樣就可以得一分,問玩家2在最優的情況下所得的分數。牌的面值為2-9,T

hdu 1150 二分匹配小點覆蓋

題意: 有兩臺機器A和B以及k個需要執行的任務。每臺機器有n,m種不同的模式,而每個任務都恰好能在一臺機器上執行。 機器A上有模式 mode_0, mode_1, …, mode_n-1,機器B上有模式: mode_0, mode_1, … , mode_m-1。 開始

HDU:2063 過山車(二分匹配

過山車 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 16791 Accepted Su

[POJ2446] Chessboard(二分匹配-匈牙利算法)

con clas sed img find span ble names printf 傳送門 把所有非障礙的相鄰格子彼此連一條邊,然後求二分圖最大匹配,看 tot * 2 + k 是否等於 n * m 即可。 但是連邊不能重復,比如 a 格子 和 b 格子 相鄰

POJ1469 COURSES 【二分匹配&#183;HK算法】

pri number break integer iss pre win rop find COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17777 Acce

51Nod 2006 飛行員配對(二分匹配)-匈牙利算法

51nod 接下來 return ace false ret else ans end 2006 飛行員配對(二分圖最大匹配) 題目來源: 網絡流24題 基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題 收藏 關註 第二次世

小點覆蓋,二分匹配—POJ1274 POJ1469 POJ1469

-s 要求 ini vector ++ %d () tin clas 二分圖最大匹配常用的匈牙利算法,之前寫的很幼稚,雖然也過了,但是平白的比別人多開了兩倍的空間。 本來就是在填加邊的時候把左邊的點和右邊的點分開算都加在圖裏面儲存,然後匹配的時候就互相匹配 match[u]

匈牙利算法dfs模板 [二分][二分匹配]

二分圖最大匹配 include logs ios 最終 namespace continue clu () 最近學了二分圖最大匹配,bfs模板卻死活打不出來?我可能學了假的bfs 於是用到了dfs模板 尋找二分圖最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是尋找增

bzoj 1059: [ZJOI2007]矩陣遊戲 [二分][二分匹配]

sam auto round 包含 bool edge port void 最大 Description   小Q是一個非常聰明的孩子,除了國際象棋,他還很喜歡玩一個電腦益智遊戲——矩陣遊戲。矩陣遊戲在一個N *N黑白方陣進行(如同國際象棋一

acd - 1403 - Graph Game(博弈 + 二分匹配

-- target ++i con -1 dsm return 中一 inf 題意:N與P在玩遊戲,N有 n1 個點,P有 n2 個點,N的點與P的點之間有 m 條無向邊。將一個石子放在當中一點。N先移動石子。沿邊移動一次,石子移動前的點及與該點相連的邊被刪除。接著

【BZOJ4950】lydsy七月月賽 C 二分匹配

for 但是 需要 com 成了 strong div mic printf 【BZOJ4950】lydsy七月月賽 C 題面 題解:比較直接的想法就是:每行,每列的最大值都留下,剩下的格子都變成1。但是如果一個格子既是行的最大值又是列的最大值,那麽我們只需要把它留下即

打鳥 二分匹配

include string 遊戲 ica times || 輸出 margin cout 有一款名叫打鳥的遊戲,遊戲中有 mm 只鳥在一個 n \times nn×n 的網格中。你可以每次選擇消滅一橫排的鳥,也可以選擇消滅一豎排的鳥(小鳥那麽萌,為什麽要消滅他)。你的任