1. 程式人生 > >hdu 1045 Fire Net 【二分圖匹配】

hdu 1045 Fire Net 【二分圖匹配】

進行 col numbers res clu 意思 archive 多少 color

<題目鏈接>

<轉載於 >>> >

題目大意:

題意思是給出一張圖,圖中‘X‘表示wall,‘.‘表示空地,可以放置炮臺,同一條直線上只能有一個炮臺,除非有‘X‘隔開,問在給出的圖中最多能放置多少個炮臺。

解題分析:

本題可用DFS求解 >>> ,但是二分匹配的想法更加巧妙,效率也更高。二分匹配的主要思想就是,對矩陣的行連通塊和列連通塊進行標號,然後根據矩陣的每個點,建立對應的行連通塊和列連通塊之間的匹配關系,然後利用匈牙利進行正式匹配,這樣當某個行聯通塊與某個列連通塊正式確立匹配關系的時候,說明這兩個連通塊的交點坐標(之一)放碉堡,而它們的其它部分則不能放碉堡。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 int uN,vN;
 6 int g[20][20];
 7 int linker[20];
 8 bool used[20];
 9 char map[5][5];
10 int mapr[5][5];
11 int mapl[5][5];
12 bool dfs(int u)
13 {
14     int v;
15     for(v=1;v<=vN;v++)
16 if(g[u][v]&&!used[v]) 17 { 18 used[v]=true; 19 if(linker[v]==-1||dfs(linker[v])) 20 { 21 linker[v]=u; 22 return true; 23 } 24 } 25 return false; 26 } 27 int hungary()
28 { 29 int res=0; 30 int u; 31 memset(linker,-1,sizeof(linker)); //將行連通塊的歸屬全部置為空 32 for(u=1;u<=uN;u++) 33 { 34 memset(used,0,sizeof(used)); 35 if(dfs(u))res++; 36 } 37 return res; 38 } 39 int main() 40 { 41 int i,j,n; 42 while(scanf("%d",&n),n) 43 { 44 memset(mapl,0,sizeof(mapl)); 45 memset(mapr,0,sizeof(mapr)); 46 memset(g,0,sizeof(g)); 47 for(i=1;i<=n;i++) 48 for(j=1;j<=n;j++) 49 { 50 cin>>map[i][j]; 51 if(map[i][j]==X) 52 mapl[i][j]=mapr[i][j]=-1; //X點的行連通編號和列連通編號均標為-1 53 } 54 int p1=0; 55 uN=0;vN=0; 56 //給行編號 57 for(i=1;i<=n;i++) 58 for(j=1;j<=n;j++) 59 { 60 while(mapr[i][j]==-1&&j<=n) //跳過這一行的X部分 61 j++; 62 p1++; //p1代表序號 63 while(mapr[i][j]!=-1&&j<=n) 64 { 65 mapr[i][j]=p1; //給第i行連續的連通塊打上相同標號p1 66 if(uN<p1) uN=p1; //記錄所有行中,行聯通塊的最大編號 67 j++; 68 } 69 } 70 int p2=0; 71 //給列編號 72 for(j=1;j<=n;j++) 73 for(i=1;i<=n;i++) 74 { 75 while(mapl[i][j]==-1&&i<=n) //遍歷第j列的時候,跳過X部分 76 i++; 77 p2++; 78 while(mapl[i][j]!=-1&&i<=n) 79 { 80 mapl[i][j]=p2; //給第j列的連續的聯通塊標上相同的序號 81 if(vN<p2) vN=p2; //記錄下所有列中,列連通塊的最大標號 82 i++; 83 } 84 } 85 //建圖 86 for(i=1;i<=n;i++) 87 for(j=1;j<=n;j++) 88 { 89 if(mapr[i][j]!=-1&&mapl[i][j]!=-1) 90 g[mapr[i][j]][mapl[i][j]]=1; //將每個空格點的行連通標號與列連通標號 構建匹配關系 91 } 92 printf("%d\n",hungary()); 93 } 94 return 0; 95 }

  • 2018-11-10

hdu 1045 Fire Net 【二分圖匹配】