CQBZOJ 郵遞員(直播剪枝技巧)

2022-09-19 07:03:13 字數 2970 閱讀 3414

題目描述

mirko在乙個山鎮找到了乙份郵遞員的工作。這個鎮可以看作乙個n*n的矩形。每個區域可能是以下之一:房子k,郵政局p,草地 『.』。每個區域都有乙個海拔。

每天早上,mirko要送信給鎮上所有的家庭。他從郵局p處開始,可以向8個方向到相鄰的乙個區域,當他送完最後乙份信後,他必須回到郵局。

現在用mirko走過的路線中海拔最高點和最低點之差來表示他的疲勞程度。幫他計算出送出所有的信最少的疲勞值。

輸入 第一行包含整數n(2<=n<=50)。接下來的n行表示矩形。p只出現一次,而k最少出現一次。

接下來n行每行包含n個正整數,表示相應區域的海拔。均小於1000000.

輸出 單獨的一行,乙個整數,表示最小的疲勞值。

樣例輸入

2 p.

.k

2 1

3 2

樣例輸出

0多麼有(wei)趣(suo)的一道題啊!!!!!!!!!

多麼有(wei)趣(suo)的一道題啊!!!!!!!!!

多麼有(wei)趣(suo)的一道題啊!!!!!!!!!

(重要的事情說三遍)

題解很多人都yy到了——二分疲勞度,列舉最小海拔,搜尋驗證

但給我的結果是

tle 2000ms+

超時**如下:

#include

#include

#include

#include

#include

#include

using

namespace

std;

struct nodep[2501];

int height[51][51];

intmap[51][51];

int n,cnt;

seth;

int getint()

void getmap()

}int u[8]=,z[8]=;

void bfs()

}}bool work(int minh,int maxh)

int main()

if(p)r=mid;

else l=mid+1;

}printf("%d",l);

}

or

z=or

z=or

z=or

z過不了,正解也yy不到,那就只有拿起菜刀,剪枝去

拿著菜刀,細看每一段**,刀尖落在了這一段:

for(iter=h.begin();iter!=h.end();iter++)

if(work(*iter,*iter+mid))

在列舉的過程中,總會列舉到一些最小海拔,大於了郵局或住宅的海拔,

或最大海拔,小於了郵局或住宅的海拔

豈能容忍?剪!!

設minh與maxh為停留點的最小最大海拔

更改為:

for(iter=h.begin();iter!=h.end();iter++)

if(*iter<=minh&&*iter+mid>=maxh)

if(work(*iter,*iter+mid))

交上去 tle 1108ms

剪了不少!

又挑到了一段:

int l=0,r=1000000;
二分範圍能不能剪呢?

我猛然發現,最小疲勞一定不小於maxh-minh,而最大疲勞一定小於等於整張地圖的最高海拔減最低海拔

改了之後交上去 tle 1009ms

加油!努力!還差9ms

挑來挑去,還是在驗證中的bfs中入手吧

我驗證的方法是將不在海拔範圍內的點標記後,從一號停留點開始遍歷全圖,看看每乙個停留點是否被遍歷到

等等,既然是遍歷,沒有其他最短路或極值的操作,那dfs的訪問次數與bfs是一樣的,而且bfs的係數還比較大

欣欣然將bfs改為dfs

懷著雞凍的心情,我交了**

ac 877ms

23333333333333333333333333333333333333333~~~~~~~~~~~~~~~~

功夫不負有心人,在精(sang)雕(xin)細(bing)琢(kuang)的剪枝下,ac了!!!!!

**如下:

#include

#include

#include

#include

#include

#include

using

namespace

std;

struct nodep[2501];

int height[51][51];

intmap[51][51];

int n,cnt;

seth;

int getint()

void getmap()

}int u[8]=,z[8]=;

void bfs()

}}void dfs(int x,int y)

}bool work(int minh,int maxh)

int main()

_minh=min(_minh,height[i][j]);

_maxh=max(_maxh,height[i][j]);

}int l=maxh-minh,r=_maxh-_minh;

while(lbool p=0;

int mid=(l+r)>>1;

for(iter=h.begin();iter!=h.end();iter++)

if(*iter<=minh&&*iter+mid>=maxh)

if(work(*iter,*iter+mid))

if(p)r=mid;

else l=mid+1;

}printf("%d",l);

}

郵遞員送信

題目描述 有乙個郵遞員要送東西,郵局在節點1.他總共要送n 1樣東西,其目的地分別是2 n。由於這個城市的交通比較繁忙,因此所有的道路都是單行的,共有m條道路,通過每條道路需要一定的時間。這個郵遞員每次只能帶一樣東西。求送完這n 1樣東西並且最終回到郵局最少需要多少時間。輸入輸出格式 輸入格式 第一...

JZOJ A組 郵遞員

郵局需要你來幫助他們為某個郵遞員設計出一條能夠穿過那遙遠鄉村的所有村子和小路至少一次的郵路 輸入資料將會保證這麼一條路是一定存在的 但是,每條路線都是有乙個花費的。各個村子裡的村民希望郵遞員到達他們村子的時間越早越好。因此,各個村子裡的人們採用了一些措施 假設第i號村子是郵遞員在他的郵遞路線上到達的...

郵遞員送信(最短路)

郵遞員送信 題目描述 有乙個郵遞員要送東西,郵局在結點1。他總共要送n 1樣東西,其目的地分別是2 n。由於這個城市的交通比較繁忙,因此所有的道路都是單行的,共m條道路,通過每條道路需要一定的時間。這個郵遞員每次只能帶一樣東西。求送完這n 1樣東西並且最終回到郵局最少需要多少時間。輸入檔案 輸入檔案...