1. 程式人生 > 其它 >SSLOJ2206最小花費&P1576

SSLOJ2206最小花費&P1576

技術標籤:# 最短路

Description

在n個人中,某些人的銀行賬號之間可以互相轉賬。這些人之間轉賬的手續費各不相同。給定這些人之間轉賬時需要從轉賬金額里扣除百分之幾的手續費,請問A最少需要多少錢使得轉賬後B收到100元。

Input

第一行輸入兩個用空格隔開的正整數n和m,分別表示總人數和可以互相轉賬的人的對數。以下m行每行輸入三個用空格隔開的正整數x,y,z,表示標號為x的人和標號為y的人之間互相轉賬需要扣除z%的手續費(z<100)。最後一行輸入兩個用空格隔開的正整數A和B。資料保證A與B之間可以直接或間接地轉賬。

Output

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

Sample Input

3 3
1 2 1
2 3 2
1 3 3
1 3

Sample Output

103.07153164

思路

dij過掉(堆優化)
code:

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
double b[2001];
int e=1,first[2001];
struct f{
 int b;
 double d;
 int net;
} a[201001];
bool book[2001];
struct
f2{ double x; int y; } p; bool operator <(const f2 &x,const f2 &y) { return x.x>y.x; } priority_queue<f2> c; void jb(int x,int y,double z) { a[e].b=y; a[e].d=z; a[e].net=first[x]; first[x]=e; e++; } int main() { int n,m,q,q2; scanf("%d%d",&n,&m); int
x,y,z; for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); jb(y,x,z*1.0/100.0); jb(x,y,z*1.0/100.0); } scanf("%d%d",&q2,&q); for (int i=1;i<=n;i++) b[i]=0x7fffffff; b[q2]=100; p.x=100.0,p.y=q2; c.push(p); for (int j=1;j<n&&c.size()&&book[q]==0;j++) { while (book[c.top().y]&&c.size()>1) c.pop(); f2 xx=c.top(); c.pop(); int u=xx.y; book[u]=1; for(int i=first[u];i!=0;i=a[i].net) { if(b[u]/(1-a[i].d)<b[a[i].b]) { b[a[i].b]=b[u]/(1-a[i].d);//注意這裡的柿子(式子) p.x=b[a[i].b]; p.y=a[i].b; c.push(p); } } } printf("%.8f",b[q]); return 0; }