Djikstra演算法訓練 題一 最小花費

2021-10-07 21:59:28 字數 3140 閱讀 9931

這是繼dijkstra演算法講解後的第一篇練習題,題目為最小花費,我先上**,這題跟我們的講解裡的模板題有點類似,但也有很大的不同,可以歸為兩種題型。**裡我就不注釋了。

題目:

【題目描述】

在n個人中,某些人的銀行賬號之間可以互相轉賬。這些人之間轉賬的手續費各不相同。

給定這些人之間轉賬時需要從轉賬金額裡扣除百分之幾的手續費,

請問a最少需要多少錢使得轉賬後b收到100元。

【輸入】

第一行輸入兩個正整數n,m,分別表示總人數和可以互相轉賬的人的對數。

以下m行每行輸入三個正整數x,y,z,

表示標號為x的人和標號為y的人之間互相轉賬需要扣除z%的手續費 (z<100)。

最後一行輸入兩個正整數a,b。資料保證a與b之間可以直接或間接地轉賬。

【輸出】

輸出a使得b到賬100元最少需要的總費用。精確到小數點後8位。

【輸入樣例】

3 31 2 1

2 3 2

1 3 3

1 3【輸出樣例】

103.07153164

#include

#define n 10001

using

namespace std;

int n, m, a, b;

double map[n]

[n], dist[n]

;void

dijkstra

(int u)

;for

(int i =

1; i <= n; i++

) flag[u]

=true

; dist[u]=1

;for

(int i =

1; i <= n; i++)}

if(t == u)

return

; flag[t]

=true

;for

(int j =

1; j <= n; j++)}

}}}int

main()

for(

int i =

1; i <= n; i++

) cout << endl;

} cin >> a >> b;

dijkstra

(a);

for(

int i =

1; i <= n; i++

) cout <<

100/ dist[b]

<< endl;

return0;

}

思路講解

首先,我們要看清楚題目,它的目的是最少轉多少前使其最後恰好為100元。這裡我們先理清楚它是如何計算的:

這裡假設只有a,b, a轉錢給b要收w%的手續費, 最後b收到的錢為100.

即設a花費x元,公式為:x

(100

-w)=

100 所以我們要求a最少花費多少,即求 100/(

100-w)

要使花費最少,即100

-w最大。

所以我們的dist陣列可以儲存 100

-w ,跟之前的不同的是,之前存的是距離,且之前求的是最小值,我們這裡要求最大值。

所以我們在設計程式時,初始化map陣列為最大值這部就不能有了。

好了,知道這一點,我們就來看**。

其次,處理main函式:

cin >> n >> m;

memset

(dist,0,

sizeof

(dist));

for(

int i =

1; i <= m; i++

) 因為是要求最大值,我們就把最初的都設為0,dist陣列初始化為0,map陣列就不用了,測試結果為:

00.99

0.97

0.99

00.98

0.97

0.98

0 可見,我們之前0的地方全是inf,這就達到了我們想要的效果。

接下來我們就呼叫dijkstra函式,使其完成dist陣列,注意:這裡是單源最短路徑,

我們求的dist是根據 a 的值而變的。

cin >> a >> b;

dijkstra

(a);

for(

int i =

1; i <= n; i++

) cout <<

100/ dist[b]

<< endl;

return

0;

主函式完成後,大致思路也就清楚了,接下來我們完成核心函式。

bool flag[n]=;

//我們直接在外面定義bool函式,並全部設為0。

for(

int i =

1; i <= n; i++

) flag[u]

=true

; dist[u]=1

;//注意這裡為什麼設為1,因為a轉給它自己不用手續費

//以上跟模板一樣,沒有多大變動

//主要是第二部分的改動

for(

int i =

1; i <= n; i++)}

if(t == u)

return

; flag[t]

=true

;for

(int j =

1; j <= n; j++)}

}}最後再強調兩點:

1.讀入資料時,一定要寫100.0,這樣最後的結果才為double型,我剛開始寫的時候在這裡磕了半天

map[x]

[y]=

(100

- w)

/100.0

; map[y]

[x]=

(100

- w)

/100.0

;2.c++控制輸出浮點型位數的技巧,庫函式為 #include

cout << fixed<<

setprecision(8

)<<

100/ dist[b]

<< endl;

好了,這題的題解就寫到這,這裡是求最大值,當然也可以求最小值,至於怎麼求,讀者可以自己嘗試下。

放一套演算法訓練題

字典序最小問題 揹包相關問題 動態規劃 有1元,5元,10元,50元,100元,500元的硬幣各c1,c5,c10,c50,c100,c500枚.現在要用這些硬幣來支付a元,最少需要多少枚硬幣?假定本題至少存在一種支付方案.0 ci 10 9 0 a 10 9 輸入 第一行有六個數字,分別代表從小到...

演算法基礎訓練題 二)

2.歸併排序 10分 c時間限制 1 毫秒 c記憶體限制 1 kb 輸入描述 多組測試資料。首先輸入乙個整數n表示陣列元素個數n 然後輸入n個整數 輸出描述 輸出n個整數在一行,用空格隔開 輸入樣例 5 5 4 3 2 1 輸出樣例 1 2 3 4 5 如下 歸併排序 mergesort 是建立在歸...

藍橋杯演算法訓練題集

algo 1 區間k大數查詢 include include include include include using namespace std int a 1005 int tmp 1005 int ans 1005 bool cmp int a,int b int maxsort int l...