SSLOJ2206最小花費&P1576
阿新 • • 發佈:2020-12-31
技術標籤:# 最短路
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;
}