《演算法競賽高階指南》2 7Astar

2021-09-26 03:14:06 字數 4230 閱讀 6441

給定一張n個點(編號1,2…n),m條邊的有向圖,求從起點s到終點t的第k短路的長度,路徑允許重複經過點或邊。

注意: 每條最短路中至少要包含一條邊。

輸入格式

第一行包含兩個整數n和m。

接下來m行,每行包含三個整數a,b和l,表示點a與點b之間存在有向邊,且邊長為l。

最後一行包含三個整數s,t和k,分別表示起點s,終點t和第k短路。

輸出格式

輸出佔一行,包含乙個整數,表示第k短路的長度,如果第k短路不存在,則輸出「-1」。

資料範圍

1≤s,t≤n≤1000,

0≤m≤105,

1≤k≤1000,

1≤l≤100

輸入樣例:

2 21 2 5

2 1 4

1 2 2

輸出樣例:

14

/*

a* star

在最短路徑問題中,如果所有邊權都是非負的,那麼就可以使用啟發函式來優化bfs過程。

啟發函式:

dist + f(s)

只要f(s) <= g(s) (以及單調性),就可以保證,當某個狀態s,第一次從優先佇列**來時,它的距離就一定是最短距離了。

1.建立反圖,然後在反向圖上求出從終點t到其他所有點的最短距離,作為每個點的估價函式

2.從起點s開始擴充套件,每次取出當前的估計值最下的點,將其所有能擴充套件到的點全部擴充套件。估計值 = 距離起點的真是距離 + 估價函式

3.當第k次遇到t時,就求出了從s到t的第k短路

*/#include

#include

#include

#include

using namespace std;

typedef pair<

int,

int> pii;

typedef pair<

int, pii> piii;

const

int n =

1010

, m =

200010

;int n, m;

int h[n]

, rh[n]

, e[m]

, w[m]

, ne[m]

, idx;

int dist[n]

, f[n]

, st[n]

;//到每個點的最短距離 點的值 重複次數

int s, t, k;

void

add(

int*h,

int a,

int b,

int c)

void

dijkstra()

);while

(heap.

size()

));}

}}memcpy

(f, dist,

sizeof f);}

inta_star()

});//按估價函式排序

memset

(st,0,

sizeof st)

;while

(heap.

size()

)});

}}return-1

;}intmain()

scanf

("%d%d%d"

,&s,

&t,&k);if

(s == t) k ++

;dijkstra()

;printf

("%d\n"

,a_star()

);return0;

}

在乙個3×3的網格中,1~8這8個數字和乙個「x」恰好不重不漏地分布在這3×3的網格中。

例如:1 2 3

x 4 6

7 5 8

在遊戲過程中,可以把「x」與其上、下、左、右四個方向之一的數字交換(如果存在)。

我們的目的是通過交換,使得網格變為如下排列(稱為正確排列):

1 2 3

4 5 6

7 8 x

例如,示例中圖形就可以通過讓「x」先後與右、下、右三個方向的數字交換成功得到正確排列。

交換過程如下:

1 2 3   1 2 3   1 2 3   1 2 3

x 4 6 4 x 6 4 5 6 4 5 6

7 5 8 7 5 8 7 x 8 7 8 x

把「x」與上下左右方向數字交換的行動記錄為「u」、「d」、「l」、「r」。

現在,給你乙個初始網格,請你通過最少的移動次數,得到正確排列。

輸入格式

輸入佔一行,將3×3的初始網格描繪出來。

例如,如果初始網格如下所示:

1 2 3

x 4 6

7 5 8

則輸入為:1 2 3 x 4 6 7 5 8

輸出格式

輸出佔一行,包含乙個字串,表示得到正確排列的完整行動記錄。

如果不存在解決方案,則輸出」unsolvable」。

輸入樣例:

2 3 4 1 5 x 7 6 8

輸出樣例

ullddrurdllurdruldr

/*

八數碼問題無解, 當且僅當 逆序對數量是奇數.

1~8每個數和最終位置的曼哈頓距離之和

string, unordered_map*/

#include

#include

#include

#include

#include

using namespace std;

intf

(string state)

return res;

}string bfs

(string start)

, dy[4]

=;//上右下左

char op[4]

=;string end =

"12345678x"

; unordered_mapint> dist;

//當前距離

unordered_map st;

//當前狀態是不是被搜過

unordered_mapchar

>> prev;

priority_queueint, string>

, vectorint, string>>

, greaterint, string>>

> heap;

heap.

push()

; dist[start]=0

;while

(heap.

size()

) string source = state;

for(

int i =

0; i <

4; i ++);

heap.

push()

;}swap

(state[x *

3+ y]

, state[a *

3+ b]);

}}} string res;

while

(end != start)

reverse

(res.

begin()

, res.

end())

;return res;

}int

main()

int t =0;

for(

int i =

0; i < seq.

size()

; i++

)for

(int j = i +

1; j < seq.

size()

; j ++)if

(seq[i]

> seq[j]

) t ++;if

(t %2)

puts

("unsolvable");

else cout <<

bfs(g)

<< endl;

return0;

}

《演算法競賽高階指南》 防曬

有c頭奶牛進行日光浴,第i頭奶牛需要minspf i 到maxspf i 單位強度之間的陽光。每頭奶牛在日光浴前必須塗防曬霜,防曬霜有l種,塗上第i種之後,身體接收到的陽光強度就會穩定為spf i 第i種防曬霜有cover i 瓶。求最多可以滿足多少頭奶牛進行日光浴。輸入格式 第一行輸入整數c和l。...

《演算法競賽高階指南》蚯蚓

蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓,第 i 只蚯蚓的長度為 ai 所有蚯蚓的長度都是非負整數,即可能存在長度為0的蚯蚓。每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那乙隻,將其切成兩段。若有多隻最長的,則任...

演算法競賽高階指南筆記

原碼 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其餘位表示值.比如如果是8位二進位制 其中,第一位為1是負數 1 0000 0001 原 1 1000 0001 原 因此,8位二進位制數的取值範圍 127,127 補碼正數的補碼是其本身 負數的補碼是在其原碼的基礎上,符號位不變,其餘各位取...