[luogu]P1576最小花費-最短路裸題
阿新 • • 發佈:2019-02-14
題目背景
題目描述
在n個人中,某些人的銀行賬號之間可以互相轉賬。這些人之間轉賬的手續費各不相同。給定這些人之間轉賬時需要從轉賬金額里扣除百分之幾的手續費,請問A最少需要多少錢使得轉賬後B收到100元。
輸入輸出格式
輸入格式:第一行輸入兩個正整數n,m,分別表示總人數和可以互相轉賬的人的對數。
以下m行每行輸入三個正整數x,y,z,表示標號為x的人和標號為y的人之間互相轉賬需要扣除z%的手續費 (z<100)。
最後一行輸入兩個正整數A,B。資料保證A與B之間可以直接或間接地轉賬。
輸出格式:輸出A使得B到賬100元最少需要的總費用。精確到小數點後8位。
輸入輸出樣例
輸入樣例#1:3 3 1 2 1 2 3 2 1 3 3 1 3輸出樣例#1:
103.07153164
說明
1<=n<=2000,m<=100000
#include<bits/stdc++.h> using namespace std; const int MAXN=100005; int n,m,a,c; double dis[MAXN],f[2005][2005]; bool b[MAXN]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int aa,bb,cc; scanf("%d%d%d",&aa,&bb,&cc); f[aa][bb]=f[bb][aa]=(100.0-cc)/100.0;//手續費 dis[i]=0.0; } scanf("%d%d",&a,&c); for(int i=1;i<=n;i++) dis[i]=f[a][i]; dis[a]=1;b[a]=1; for(int i=1;i<=n;i++){ double mn=0.0; int k=0; for(int j=1;j<=n;j++){ if(dis[j]>mn && !b[j]){ mn=dis[j]; k=j; } } if(k==c) break; dis[k]=mn; b[k]=1; for(int j=1;j<=n;j++){ if(!b[j] && f[k][j]*dis[k]>dis[j]) dis[j]=f[k][j]*dis[k]; } } printf("%.8lf",100/dis[c]); }