NOIP2010 引水入城

2022-05-05 17:48:09 字數 1345 閱讀 6126

傳送門

一道非常好的搜尋題!

題目要求乙個城市能修建水利工程,必須在乙個比他海拔高而且修建了水利工程的城市旁邊,那我們可以從每個水庫旁邊的點開始進行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列的矩形,如上圖所示,其中每個格仔都代表一座城 市,每座城市都有乙個海拔高度。為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施 有兩種,分別為蓄水廠和輸...