[SSL] 2206 minimum cost
Time Limit:1000MS
Memory Limit:65536K
Description
Among n individuals, the bank accounts of some people can transfer money to each other. The fees for transfers between these people vary. Given that when transferring money between these people, what percentage of the handling fee needs to be deducted from the transfer amount, how much is the minimum amount A needs to make B receive 100 yuan after the transfer.
Input
On the first line, enter two positive integers n and m separated by spaces, which represent the total number of people and the logarithm of people who can transfer money to each other. Enter three positive integers x, y, z separated by spaces in each line of the following m lines, which means that the transfer between the person labeled x and the person labeled y needs to deduct z% of the handling fee (z<100). Enter two positive integers A and B separated by spaces on the last line. Data guarantee can be transferred directly or indirectly between A and B.
Output
Output A makes B arrive at the minimum total cost of 100 yuan. Accurate to 8 decimal places.
Sample Input
3 3
1 2 1
2 3 2
1 3 3
1 3
Sample Output
103.07153164
Hint
For all data, 1<=n<=2000.
Ideas
Use dijkstra .
Take B as the starting point.
Use heap optimization.
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
struct jgt
{
int w;
double s;
};
struct NOTE
{
int x,y,nxt;
double s;
}f[4000010];
bool operator < (const jgt &a,const jgt &b)
{
return a.s>b.s;
}
priority_queue<jgt>q;
int n,m,dx,dy,tot=0;
int head[2010];
double dis[2010];
bool d[2010];
void input()
{
int i,j,x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
tot++;//建边
f[tot].x=x;
f[tot].y=y;
f[tot].s=(100-z)/100.0;
f[tot].nxt=head[x];
head[x]=tot;
tot++;
f[tot].x=y;
f[tot].y=x;
f[tot].s=(100-z)/100.0;
f[tot].nxt=head[y];
head[y]=tot;
}
scanf("%d%d",&dx,&dy);
return;
}
void DIJ()
{
jgt tem,temp;
int i,j,mn,w,v;
for(i=0;i<=n;i++)
dis[i]=100000000;
for(i=head[dy];i>0;i=f[i].nxt)
{
dis[f[i].y]=100.0/f[i].s;
tem.w=f[i].y;
tem.s=dis[f[i].y];
q.push(tem);
}
for(dis[dy]=100,d[dy]=1;!q.empty();)//用小顶堆
{
tem=q.top();
q.pop();
d[tem.w]=1;
for(j=head[tem.w];j>0;j=f[j].nxt)//松弛
{
if(!d[f[j].y]&&tem.s/f[j].s<dis[f[j].y])
{
dis[f[j].y]=tem.s/f[j].s;
temp.w=f[j].y;
temp.s=dis[f[j].y];
q.push(temp);
}
}
}
return;
}
int main()
{
input();
DIJ();
printf("%.8lf",dis[dx]);
return 0;
}