最短路問題(1)

2021-06-26 00:54:51 字數 4639 閱讀 1443

從圖中指定的一點出發走到某一目標點如果存在多種不同的走法,

最短的是哪條路?其長度是多少?

圖論中解決上述問題的方法都屬於最短路演算法。由於圖的特點不同、

儲存結構不同、確立演算法的側重方向不同,所以演算法是多種多樣的。

一 無權圖及樹網

在無權圖中,路徑長度只與路徑上的點數有關,而與路徑上的邊權和點權無關。

例如廣搜那節課例題2「方格圖上求從s到e的最短路」一題。

不少多維(多分量)的圖(包括許多抽象圖)的最短路都屬於此類。

由於廣搜就是逐層展開的,所以很適合解決此類問題。

例題1 跳棋

某種跳棋共有5個格仔排成一排,

其中兩格放黑子、兩格放白子,還有一格為空。

跳棋規則允許緊鄰空格的棋子走入空格,還允許把乙個棋子隔著另乙個棋子跳入空格。

求把棋子的一種分布狀態變成另一種分布狀態至少經過多少步?

先輸入乙個長度5且含有兩個1、兩個2、乙個0的數字串,表示原來的分布狀態,

再輸入另乙個長度5且含有兩個1、兩個2、乙個0的數字串,表示後來的分布狀態。

輸出就是最少步數。 分析

把5個位置看成「5維空間(5個分量決定)中的點」,問題就是求從出發點到目標點的最少步數了。

由於圖中的點可能被重複搜尋,所以需要標記搜過的點。(雜湊登記)

又由於每個點的步數都可以從其上游一點的步數加1求得,所以應當建立所有點的步數表。

#include

#include

#include

#include

using namespace std;

int s[3][3][3][3];

string a,b,c;

queueq;

void bfs()

} q.pop(); }

}int main()

由於在樹狀結構中,任意兩點間的路徑是唯一的,因此,廣搜可以求得最短路。

它既是最短路也是最長路。

練習 1 倒公尺

3個儲存公尺的容器容量分別是3、5、8公升,

如果分別放有1、2、5公升公尺,最少倒幾次公尺能評分為兩個4公升?倒幾次能倒成2、5、1公升?

輸入第一行3個整數分別代表3、5、8公升容器中原有公尺數,

第二行3個整數分別代表3、5、8公升容器中希望的公尺數。

如果倒得成就輸出最少倒公尺次數,否則輸出-1.

樣例輸入

0 2 7

3 1 5

輸出 2

樣例說明:

0 2 7倒成 0 1 8 倒成 3 1 5

2 九宮格遊戲

3行3列9個格仔中分別放著1到8的8個數字另有乙個空格。

每次可把緊鄰空格的數字移入空格,至少移動多少次才能變為目標分布?

如果無法實現輸出-1,否則輸出最少移動次數。

輸入3個長度為3的數字串表示原來的分布,

在輸入3個長度為3的數字串表示後來的分布。

0表示空格。

3 noip提高組2002 字串變換

4 noip提高組2007 樹網的核

5 海淀2013 拉燈

拉燈遊戲 lamp.cpp|c|pas

n盞燈從左到右放成一排,每盞燈由乙個拉線開關來控制。

開始燈都未亮,求在滿足下面拉燈規則的前提下,把所有燈都拉亮的最少拉燈線次數。 規則

拉第i盞燈的燈線必須同時滿足下面兩個前提條件:

① 若i>1,則第i-1盞燈必須是滅著的。

② 若i>2,則號數不大於i-2的燈都是亮著的。

輸入檔名為lamp.in中僅有乙個正整數n,代表燈盞總數。

輸出檔案lamp.out中也僅有乙個整數表示最少拉燈線次數。

輸入輸出樣例

lamp.in 3

lamp.out 5

樣例說明:

原來3盞燈的狀態          滅滅滅

拉1燈變成    亮滅滅

拉3燈變成    亮滅亮

拉1燈變成    滅滅亮

拉2燈變成    滅亮亮

拉1燈變成    亮亮亮

資料範圍:

80%的資料滿足n<20

90%的資料滿足n<30

100的資料滿足n<100

選作noip2013day2 華容道

二 可拓撲圖

1 直接計算 例如noip普及組2004 花生採摘

2 動歸 例如跳馬、飛翔、傳遞物品等

最長單調子串行的平方演算法也可看做此類演算法,它自然而然就是乙個拓撲序列,

所以按拓撲順序動歸很容易進行。

由於無圈,所以地推關係得以實現。

例題2 海淀2010競賽 限體力上樓梯

三 上樓梯 程式檔案主名stairs

明明上n級台階可用4種步幅,當然每種步幅花費的體力也不一樣,對應關係如下:

步幅大小    體力花費

1       1

2       3

3       6

4       10

明明開始共有m個體力,求他最少要跨多少步才能上完所有台階?

輸入檔名為stairs.in。其中只有n和m兩個正整數,中間用空格做間隔符。0

對於30%的資料,m<100

對於60%的資料,m<10000

對於80%的資料,m<1000000

對於100%的資料,m<10^19

輸出檔名為stairs.out,其內容只有題目所求的最少步數這乙個數。

輸入輸出樣例

stairs.in的內容為:

3 5則stairs.out的內容為: 2

分析 此圖顯然拓撲,而且屬於最短路型別。

可設f[i][j]為用j個體力上i級台階的最少步數

#include

#include

using namespace std;

ifstream fin("stairs.in");

ofstream fout("data.out");

//f[louti][tili]=最少步數

int f[4010][10000];

int main() ;

for(i=0;i

for(j=i;j

for(k=1;k<=4;k++)

if(f[i][j]+1

f[i+k][j+t[k]]=f[i][j]+1;

for(j=n;j<=m;j++)

s=min(s,f[n][j]);

fout<

return 0; }

練習6 1變n的最小代價

如果整數c=a*b,

則c可變成c+a,代價是b。

c也可變成c+b,代價是a。

求從1變成n的最小總代價。

輸入正整數n,n<200000

輸出最小總代價。

7 noip提高組2009 烏龜棋

8 noip提高組2005 過河

9 跳馬三問

在乙個很大(座標不限、可正可負)的棋盤上,馬從a行b列出發,

只許向右跳(右上或右下不限),

求跳到c行d列最少跳多少部?最多多少部?共有多少種不同跳法?

輸入a、b、c、d4個整數, 0

10 三維飛彈攔截

bomb

題目描述

一場戰爭正在a國與b國之間如火如荼的展開。

b國憑藉其強大的經濟實力開發出了無數的遠端攻擊飛彈,b國的領導人希望,通過這些飛彈直接毀滅a國的指揮部,從而取得戰鬥的勝利!當然,a國人民不會允許這樣的事情發生,所以這個世界上還存在攔截飛彈。

現在,你是一名a國負責飛彈攔截的高階助理。

b國的飛彈有效的形成了三維立體打擊,我們可以將這些飛彈的位置抽象三維中間的點(大小忽略),為了簡單起見,我們只考慮乙個瞬時的狀態,即他們靜止的狀態。

攔截飛彈設計非常精良,可以精準的引爆對方飛彈而不需要自身損失,

但是a國面臨的乙個技術難題是,這些飛彈只懂得直線上公升。

精確的說,這裡的直線上昇指xyz三維座標單調上公升。

給所有的b國飛彈按照1至n標號,一枚攔截飛彈可以打擊的物件可以用乙個xyz嚴格單調上公升的序列來表示,例如:

b國飛彈位置:(0, 0, 0) (1, 1, 0) (1, 1, 1), (2, 2, 2)

乙個合法的打擊序列為:

乙個不合法的打擊序列為

a國領導人將乙份飛彈位置的清單交給你,並且向你提出了兩個最簡單不過的問題(假裝它最簡單吧):

求1枚攔截飛彈最多可以摧毀多少b國的飛彈?

不管是為了個人榮譽還是國家榮譽,更多的是為了飯碗,你,都應該好好的把這個問題解決掉!

輸入檔案

第一行乙個整數n給出b國飛彈的數目。

接下來n行每行三個非負整數xi, yi, zi給出乙個飛彈的位置,你可以假定任意兩個飛彈不會出現在同一位置。

輸出檔案

輸出檔案僅有1行。輸出乙個整數p,表示一枚攔截飛彈之多能夠摧毀的飛彈數。

樣例輸入

4               

0 0 0         

1 1 0

1 1 1

2 2 2

樣例輸出 3

資料約定

所有的座標都是[0,106]的整數

對於30%的資料滿足n  31

對於50%的資料滿足n  101

對於100%的資料滿足n  1001

最短路問題 1

本蒟蒻記性不太好怕忘 一樣的說辭 咳,寫這篇最短路的文章來紮實自己的基礎 同時讓自己搞的更明白點 在做圖論題的時候,我們往往會通過最短路來進行一些操作,在這篇和下篇文章裡我將會介紹 dijkstra 和 spfa 兩種常見的方法來解決最短路問題。dijkstra 可以說是最經典的最短路演算法之一了,...

最短路 最短路徑問題

題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點直線的距離。現在的任務是找出從一點到另一點之間的最短路徑。input 共有n m 3行,其中 第一行為乙個整數n。第2行...

最短路總結1 最短路問題概述與樸素dijkstra

最短路系列鏈結 最短路總結1 最短路問題概述與樸素dijkstra 最短路總結2 堆優化dijkstra 最短路總結3 bellmanford 最短路總結4 spfa及應用 最短路總結5 floyd 1.最短路問題概述 若網路中的每條邊都有乙個數值 長度 成本 時間等 則找出兩節點 通常是源節點和阱...