第三部分 數據結構 --第四章 圖論算法1344:【例4-4】最小花費

1344:【例4-4】最小花費

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 4204 通過數: 1843
【題目描述】
在n個人中,某些人的銀行賬號之間可以互相轉賬。這些人之間轉賬的手續費各不相同。給定這些人之間轉賬時需要從轉賬金額里扣除百分之幾的手續費,請問A最少需要多少錢使得轉賬後B收到100元。

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

以下m行每行輸入三個正整數x,y,z,表示標號爲x的人和標號爲y的人之間互相轉賬需要扣除z%的手續費 (z<100)。

最後一行輸入兩個正整數A,B。數據保證A與B之間可以直接或間接地轉賬。

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

【輸入樣例】
3 3
1 2 1
2 3 2
1 3 3
1 3
【輸出樣例】
103.07153164
【提示】
【數據規模】

1≤n≤2000


思路:
Dijkstra
(1)a [ i ] [ j ] 存轉賬率

(2)dis [ i ] 是 a [ 起點 ] [ i ]

(3)f [ i ] 判斷是否已經嘗試過

(4)前驅結點 k


所求的結果 :ans * a[x][y]=100 即 ans=100 / a[x][y]


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 2001
using namespace std;
double a[N][N],dis[N],minn;
int f[N],n,m,k,x,y;
void read(){
	int xx,yy,zz;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= m; i++)
	{
		scanf("%d%d",&xx,&yy);
		scanf("%lf",&a[xx][yy]);
		a[xx][yy] = (100 - a[xx][yy])/100;
		a[yy][xx] = a[xx][yy];
		}
		cin >> x >> y;
	}
	void dijkstra(int x){//dijkstra 算法
		for(int i = 1; i <= n; i++)
		dis[i] = a[x][i];
		dis[x] = 1;
		f[x] = 1;
		for(int i = 1; i <= n-1;i++)
		{
			minn = 0;
			for(int j = 1; j <= n; j++)
			if(!f[j] && dis[j] > minn)
			{
				k = j;
				minn = dis[j];
			}
			f[k] = 1;
			if(k == y) break;
			for(int j = 1; j <= n; j++)
			if(!f[j] && dis[k]*a[k][j] > dis[j])
			dis[j] = dis[k] * a[k][j];
		}
	}
	int main(){
		read();
		dijkstra(x);
		printf("%.8lf",100/dis[y]);//ans * a[x][y]=100 即 ans=100 / a[x][y]
		return 0;
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章