1. 程式人生 > >POJ 3020 Antenna Placement【二分匹配——最小路徑覆蓋】

POJ 3020 Antenna Placement【二分匹配——最小路徑覆蓋】

/*********************************************************************
題意:‘*’代表城市
       'o'代表空地
       要求你用最小的無線電雷達來覆蓋所有的城市
       雷達只可以建立在城市上
       每一個雷達,只可以覆蓋它自己所在的位置和與它相鄰的一個位置
       【上 || 下 || 左】
       注意:也就是說一個雷達只可以覆蓋兩個城市

演算法:二分圖的匹配 ———— 最小路徑覆蓋
      最小路徑覆蓋=最小路徑覆蓋=|G|-最大匹配數

思路:拆點,把每一個城市看成是兩個點
      具體分析還是看這篇部落格學去吧,不能比她說的更好了Orz
      http://blog.csdn.net/lyy289065406/article/details/6647040
PS:感覺還是分不怎麼清什麼時候用最小路徑覆蓋,什麼時候用最大匹配
    ╮(╯▽╰)╭先記住直接匹配的就用最大匹配
    要拆點的就用最小路徑覆蓋好了,水菜傷不起
**********************************************************************/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 40*10+10;
int map[45][15];

int g[maxn][maxn];
int linker[maxn];
int vis[maxn];
int uN,vN;


bool dfs(int u)
{
    for(int v = 1; v <= vN; v++)
    {
        if(!vis[v] && g[u][v])
        {
            vis[v] = 1;
            if(linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

int hungary()
{
    int sum = 0;
    memset(linker,-1,sizeof(linker));
    for(int u = 1; u <= uN; u++)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(u))
            sum++;
    }
    return sum;
}

int main()
{
    int T;
    int row,col;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d%*c", &row,&col);

        char c;
        int num = 0; //記錄有多少個點
        memset(map,0,sizeof(map));
        memset(g,0,sizeof(g));
        for(int i = 1; i <= row; i++) //從 1 開始, map[][]周圍加邊
        {
            for(int j = 1; j <= col; j++)
            {
                scanf("%c", &c);
                if(c == '*') map[i][j] = ++num;
            }
            getchar();
        }
        uN = vN = num;

        for(int i = 1; i <= row; i++) //建圖
        {
            for(int j = 1; j <= col; j++)
            {
                if(map[i][j])
                {
                    if(map[i][j+1])
                        g[map[i][j]][map[i][j+1]] = 1;
                    if(map[i][j-1])
                        g[map[i][j]][map[i][j-1]] = 1;
                    if(map[i+1][j])
                        g[map[i][j]][map[i+1][j]] = 1;
                    if(map[i-1][j])
                        g[map[i][j]][map[i-1][j]] = 1;
                }
            }
        }
        printf("%d\n", num-hungary()/2); //最小路徑覆蓋數
    }
    return 0;
}


相關推薦

POJ 3020 Antenna Placement二分匹配——路徑覆蓋

/********************************************************************* 題意:‘*’代表城市 'o'代表空地 要求你用最小的無線電雷達來覆蓋所有的城市 雷達只可以建立在城市上 每一個雷

Poj 1325 Machine Schedule二分匹配-------覆蓋

Machine Schedule Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14439 Accepted: 6156 Description As we all know, mach

HDU1151 Air Raid二分路徑覆蓋

Air Raid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6562 &nbs

POJ2060 Taxi Cab Scheme二分路徑覆蓋

題目連結: 題目大意: 計程車公司每天有有N項預約,每項預約有開始時間(xx:xx),出發地點(a,b)與目的地點(c,d)。 完成這項預約行駛需要的時間是|a-c| + |b-d|分鐘。一輛車可

HDU1150 Machine Schedule二分覆蓋

Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10961&

HDU-3335___Divisibility——二分匹配 | 路徑覆蓋 | DLX

題目大意:      求選出兩兩相除互不為 000 的最大個數 解題思路:     做法比較多,本人是在DLX專題裡做到所以就用DLX來做了     列舉每兩個數,若能相除為 000,則AddNode(i,j)AddNode(i,j)AddNode(i,j),

Poj-2060 Taxi Cab Scheme 二分路徑覆蓋

題目連結 計程車公司有n個預約, 每個預約有時間和地點, 地點分佈在二維整數座標系上, 地點之間的行駛時間為兩點間的曼哈頓距離(|x1 - x2| + |y1 - y2|)。一輛車可以在運完一個乘客後運另一個乘客, 條件是此車要在預約開始前一分鐘之前到達出發地, 問最少需要

POJ1325 Machine Schedule二分覆蓋

題目連結: 題目大意: 有兩臺機器A和B,機器A有N種不同的模式,編號為0~N-1。機器B有M種不同的模式,編號為0~M-1。 在一開始的時候,機器A和B都處於0模式。現在需要用兩臺機器來處理K項

poj 3020 Antenna Placement (二分路徑覆蓋)

#include<stdio.h> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<queue> #includ

POJ 3020 Antenna Placement 覆蓋

傳送門:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K

POJ 2195 Going Home 二分權值匹配

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

二分匹配入門專題1E - Air Raid hdu1151路徑覆蓋

eno rate ask return red size all file 痛苦 Consider a town where all the streets are one-way and each street leads from one intersection to

POJ - 3258 River Hopscotch 二分--最大化

題目傳送門 題目描述:第一行輸入三個整數L,N,K,表示一個長度為L的河上有N塊石頭,任意移去K塊,問任意兩塊石頭之間的最小間隔是多少(包括起始點到第一塊石頭的間隔和最後一塊石頭到終點的間隔),接下來N行是N塊石頭距離起始點的位置。 解題思路:這是一道典型的利用二分最大化最小值的題。現在

poj 2456 Aggressive cows 二分+最大化

Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21009 Accepted: 9984 Description Farmer John has built a n

POJ 25456 Aggressive cows 二分最大化

Aggressive cowsTime Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%lld & %llu Des

網絡流24題魔術球問題 二分答案+路徑覆蓋

cnblogs for getchar() str logs math 等於 active rip Description 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,...的球。 (1)每次只能在某根柱子的最上面放球。 (2)在同一根柱子

[loj #6003]「網絡流 24 題」魔術球 二分路徑覆蓋,網絡流

sqrt ted -html hide next http osi header col #6003. 「網絡流 24 題」魔術球 內存限制:256 MiB時間限制:1000 ms標準輸入輸出 題目類型:傳統評測方式:Special Judge 上傳者: 匿名

LA3126 訓練指南出租車 DAG路徑覆蓋

位置 flow 模型 play nic pen 所在 dag algorithm 題意 你在一座城市裏負責一個大型活動的接待工作。明天將有m位客人從城市的不同的位置出發,到達他們各自的目的地。已知每個人的出發時間,出發地點和目的地。你的任務是用盡量少的出租車送他們,使

hdoj3007 Buried memory 計算幾何--覆蓋

傳送門:Buried memory 蒼天饒過誰,第三次在hdoj上 交計算幾何的題了,沒一次是AC的。 ┭┮﹏┭┮都是模板題啊,我都是抄板子的啊,為什麼會這樣,我怎麼這麼菜。 題意: 求最小圓覆蓋 的 圓心,半徑,保留2位小數 分析 我的程式碼參考的是 俞勇老師的 《ACM國際大學生程式設計競賽 演

2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div 1)Afloyd 路徑覆蓋最少飛機數滿足所有航班要求

#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math