這是繼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...