1. 程式人生 > >[luogu]P1576最小花費-最短路裸題

[luogu]P1576最小花費-最短路裸題

題目背景

題目描述

在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]);
}