傳送門
一道非常好的搜尋題!
題目要求乙個城市能修建水利工程,必須在乙個比他海拔高而且修建了水利工程的城市旁邊,那我們可以從每個水庫旁邊的點開始進行bfs,判斷最後一行有哪些點能到達,從而判斷可行性。這個做法很簡單粗暴,只要一開始把沿著水庫邊上所有點全都壓到佇列裡面,直接bfs即可,時間複雜度不超過o(nm)。
可行性很好判斷,關鍵在於如何計算出最少需要多少個水庫。仔細想一想之後發現,乙個水庫能供給到的靠沙漠的城市,它必然是一段連續的區間,否則我們必然有方法使得區間聯通(只可能是中間高,只要從中間流就行了。)那我們其實是可以轉化成線段覆蓋,只要求出每個點能流到的區間是多少就好了。
又乙個暴力方法出來了……從每個點開始bfs能流到的區間。但是這樣的複雜度太大了,o(m^2*n),很可能超時。
再想一想,我們要求的是乙個點它能流到的區間的左右端點。我們其實完全可以用已經搜尋過的結果去更新答案,而沒有必要每次都重新搜尋一遍。所以解決問題的方法出現了,記憶化搜尋!只要在dfs的時候,記錄一下每個點被更新的最遠的值是多少,遇到已經走過的格仔,不搜尋直接返回即可。最後做一次線段覆蓋,直接列舉即可。注意在初始化能拓展的最左邊的端點的時候要預處理為極大值。
看一下**。
#include#include#include
#include
#include
#include
#include
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
using
namespace
std;
typedef
long
long
ll;const
int m = 505
;const
int inf = 1000000009
;const ll mod = 1e9+7
;ll read()
while(ch >= '
0' && ch <= '9'
)
return ans *op;
}int l[m][m],r[m][m],h[m][m],n,m,dx[4] = ,dy[4] = ,cnt,g = 1
;bool
vis[m][m],flag;
void dfs(int x,inty)}
intmain()
printf(
"1\n%d\n
",cnt);
return0;
}
NOIP2010 引水入城
兩遍bfs floodfill,第一遍bfs可以判斷出最後是輸出0還是輸出1,第二遍bfs floodfill不懂 program flow const dx array 1.4 of 1.1 1,0,1,0 dy array 1.4 of 1.1 0,1,0,1 type atp record x...
NOIP2010 引水入城
4引水入城在乙個遙遠的國度,一側是風景秀美的湖泊,另一側則是漫無邊際的沙漠。該國的行政區劃十分特殊,剛好構成乙個n 行m 列的矩形,如上圖所示,其中每個格仔都代表一座城市,每座城市都有乙個海拔高度。為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施有兩種,分別為蓄水廠和輸水...
NOIP 2010 引水入城
題目描述 在乙個遙遠的國度,一側是風景秀美的湖泊,另一側則是漫無邊際的沙漠。該國的行政 區劃十分特殊,剛好構成乙個n行m列的矩形,如上圖所示,其中每個格仔都代表一座城 市,每座城市都有乙個海拔高度。為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施 有兩種,分別為蓄水廠和輸...