bes
si
ebessie
bessie
想以n nn×
××n
nn網格(
1<=n
<
=500
)(1 <= n <= 500)
(1<=n
<=5
00)的形狀在危險的小行星場中導航她的飛船。網格包含k
kk個小行星(
1<=k
<=10
,000
)(1 <= k <= 10,000)
(1<=k
<=1
0,00
0),它們方便地位於網格的晶格點處。
幸運的是,貝茜擁有強大的**,可以一擊就蒸發掉網格中任何給定行或列中的所有小行星,這種**非常昂貴,因此她希望謹慎使用。欄位中,找到貝西需要射擊以消除所有小行星的最小射擊次數。
第1
11行:兩個整數n
nn和k
kk,以單個空格分隔。
第2 ~k
+1
2~k + 1
2~k+
1行:每行包含兩個空格分隔的整數r
rr和c(1
<=r
,c
<=n
)c(1 <= r,c <= n)
c(1<=r
,c<=n
),分別表示小行星的行和列座標。
第1
11行:整數,表示bes
si
ebessie
bessie
必須拍攝的最小次數。
341
1132
232
2
下圖表示資料,其中「x」
「x」「x
」是小行星,「.」
「.」「.
」是空白空間:
x .x
x.\ x
x.x.x.
.\ x.
.x..x.
.\ x.
.x.
b es
si
ebessie
bessie
可以在第1
11行射擊以摧毀(1,
1)
(1,1)
(1,1)和(1,
3)
(1,3)
(1,3
)處的小行星,然後她可以擊落第2
22列以摧毀(2,
2)
(2,2)
(2,2)和(3,
2)
(3,2)
(3,2
)處的小行星。
因此,用兩個子彈就可以解決所有敵人。
這道題其實是最小點覆蓋問題。
然後,通過某種神奇的證明,我們可以得出最小點覆蓋問題的答案就是最大匹配。
我也不會證,我是這樣理解的:
在選了那幾個點之後,所有的邊都必定有一端是那幾個點的其中乙個。
也就是說,無論你選那一條邊,都會碰到那幾個點的其中乙個。
我們要讓碰到的點不同,線盡可能的多(最大匹配的要求),就只能每的每一條邊碰到的那幾個點都不相同。
那麼也就是說,最小點覆蓋就是最大匹配了。
#include
#include
#include
using
namespace std;
struct note e[
3000001];
int n, m, o, x, y, le[
10001
], k, s, t, ans, dis[
10001];
queue<
int>q;
bool
bfs()}
return0;
}int
dfs(
int now,
int an)
return go;
}int
main()
; le[x]
= k;
//連邊
e[++k]
=(note)
; le[y]
= k;
}for
(int i =
1; i <= n; i++
); le[s]
= k;
e[++k]
=(note)
; le[i]
= k;
}for
(int i = n +
1; i <= n + m; i++
); le[i]
= k;
e[++k]
=(note)
; le[t]
= k;
}while
(bfs()
)//dinic演算法
ans +
=dfs
(s,2147483647);
printf
("%d"
, ans)
;//輸出
return0;
}
最小點覆蓋
題目連線 最小點覆蓋為 在乙個二分圖中,選取最少的點可以把所有的變覆蓋,點的最少個數就是最小點覆蓋。最小點覆蓋 最大二分匹配。克魯斯卡爾演算法。關於本題 把從零開始,轉化成從一開始。起點不用加入e,因為機器的起始狀態就是1,或者加入e但是不參加計算,我採用的是第二種。include include ...
POJ 3041 Asteroids(最小點覆蓋)
poj 3041 asteroids 題意 給出m個點的所在行列,每次可以選擇清除一行或者一列,問清除這些點的最小操作次數是多少?分析 將所有點的行看成一組,所有的點列看成一組,對每個點的行和列建一條邊,每條邊就代表乙個點,清除一行或者一列可以看成選擇二分圖中的乙個點,清除所有的點,就相當於選擇二分...
POJ 3041 Asteroids 最小點覆蓋
題意 用最少的射擊來消滅圖中的小行星。關鍵是建圖轉化,建乙個 橫座標到縱座標的二分圖,有障礙的點的位置上的值賦值為1,然後根據題意求的是二分圖的最小點覆蓋數,根據乙個定理,知道最小點覆蓋數 最大匹配數 ac include include include include include includ...