看了眼題解,貌似沒有和我的思路一樣的…
所以就來寫一篇題解…
首先我不會什麼雙向bfs也懶得寫最短路…
所以,就乙個bfs 闖遍天下
先看題:
感性理解一下…貌似如(1,2),(2,1),(1,4),(4,1)都到不了 雖然這個麼什麼用
好了,進入主題
首先,bfs是乙個佇列,為了保證結果的真確性,所以存當前花費的陣列必須符合單調性,不然就沒法達到最短路的效果了(開始就是沒注意單調,調了2個小時)可以發現乙個點可以直接到四個點,而到這四個點所花費的次數為1或0,所以只要當隊伍中有乙個點q時,把q可以花費0次就可以到達的點全部放進佇列,然後,就是乙個裸的bfs最短路了…
qa#include
using
namespace std;
int queue_spend[
1000000];
//佇列中每個位置的最少花費
int queue_x[
1000000
],queue_y[
1000000];
//佇列中的點
int tail,head,n,m;
int boo[
605]
[605];
int _map[
605]
[605];
//注意:boo判斷的是點,_map判斷的是邊
/*b c
\ /a / \
d e
a點存的是a這個點和a-e這條邊
*/int now_spead;
//記錄當前的花費
void
add(
int x,
int y,
int spend)
//加入佇列
void
around
(int first_x,
int first_y)
//向四周尋找可以不花費就可以到的點
if(boo[first_x+1]
[first_y+1]
&&_map[first_x]
[first_y]==0
)if(boo[first_x+1]
[first_y-1]
&&_map[first_x]
[first_y-1]
==1)if
(boo[first_x-1]
[first_y+1]
&&_map[first_x-1]
[first_y]==1
)}void
write
(int out)
//輸出
void
solve()
//佇列初始化
tail=1;
head=0;
boo[1]
[1]=
0;now_spead=0;
around
(queue_x[1]
,queue_y[1]
);//把一開始就可以直接到達的點放入佇列,並且花費是0
while((
++head)
<=tail)
if(_map[queue_x[head]-1
][queue_y[head]-1
]==1&&boo[queue_x[head]-1
][queue_y[head]-1
])//如果這個方向行走要花費1次的話就入隊,比較用0次的早入隊了
if(_map[queue_x[head]
][queue_y[head]]==
1&&boo[queue_x[head]+1
][queue_y[head]+1
])//以下同理
if(_map[queue_x[head]-1
][queue_y[head]]==
0&&boo[queue_x[head]-1
][queue_y[head]+1
])if(_map[queue_x[head]
][queue_y[head]-1
]==0&&boo[queue_x[head]+1
][queue_y[head]-1
])} cout<<
"no solution"
<
//無解
}int
main()
P2243 電路維修
elf 是來自gliese 星球的少女,由於偶然的原因漂流到了地球上。在她無依無靠的時候,善良的運輸隊員mark 和james 收留了她。elf 很感謝mark和james,可是一直也沒能給他們幫上什麼忙。有一天 mark 和james 的飛行車沒有辦法啟動了,經過檢查發現原來是電路板的故障。飛行車...
洛谷P2243 電路維修
題目位址 轉化為圖論問題 對於每個交叉點 x,y 抽象成節點。與它相鄰的四個點中,可以直接連線的邊權為0,否則邊權為1。用死了的 spfa解決圖論問題。include include define gc getchar define clean x,k memset x,k,sizeof x def...
洛谷2243 電路維修 廣搜 雙端佇列優化
題目描述 題意不太容易說清楚,還是看鏈結吧。題解 首先感覺是廣搜求最短路的題目。我一開始是沒想好怎麼建圖的,感覺直接亂做複雜度好像很 這個題的建圖還是有點巧妙的,建圖方法是把格點看作是圖上的點,原來的斜線看作是兩點間連邊權為0的邊,每個格仔除了原來的斜線的另一條對角線的兩點之間連一條邊權為1的邊,表...