1. 程式人生 > >[POJ3041] Asteroids(最小點覆蓋-匈牙利算法)

[POJ3041] Asteroids(最小點覆蓋-匈牙利算法)

mes 技術分享 set || tdi line isp none event

傳送門

題意:

給一個N*N的矩陣,有些格子有障礙,要求我們消除這些障礙,問每次消除一行或一列的障礙,最少要幾次。

解析:

把每一行與每一列當做二分圖兩邊的點。

某格子有障礙,則對應行與列連邊。

選出最少的點,使得所有邊被覆蓋。

最小點覆蓋。

——代碼

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #define M(x, a) memset(a, x, sizeof(a))
 4 
 5 using namespace std;
 6
7 const int MAXN = 501; 8 int n, k, cnt, ans; 9 int head[MAXN], next[MAXN * MAXN], to[MAXN * MAXN], belong[MAXN]; 10 bool vis[MAXN]; 11 12 inline void add(int x, int y) 13 { 14 to[cnt] = y; 15 next[cnt] = head[x]; 16 head[x] = cnt++; 17 } 18 19 inline bool find(int u)
20 { 21 int i, v; 22 for(i = head[u]; i != -1; i = next[i]) 23 { 24 v = to[i]; 25 if(!vis[v]) 26 { 27 vis[v] = 1; 28 if(!belong[v] || find(belong[v])) 29 { 30 belong[v] = u; 31 return 1;
32 } 33 } 34 } 35 return 0; 36 } 37 38 int main() 39 { 40 int i, x, y; 41 scanf("%d %d", &n, &k); 42 M(-1, head); 43 for(i = 1; i <= k; i++) 44 { 45 scanf("%d %d", &x, &y); 46 add(x, y); 47 } 48 for(i = 1; i <= n; i++) 49 { 50 M(0, vis); 51 if(find(i)) ans++; 52 } 53 printf("%d", ans); 54 return 0; 55 }
View Code

[POJ3041] Asteroids(最小點覆蓋-匈牙利算法)