【图论】【最短路】最小花费

时间:2019-01-18
本文章向大家介绍【图论】【最短路】最小花费,主要包括【图论】【最短路】最小花费使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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 

题意


1(A)1(A)3(B)3(B)最少付的钱
每走一个点要乘那一个点的手续费。

前言

可以先把这一道题AC了:
最短路径问题
第二种Dijkstra

思想

都在最短路径问题了
(记得是第二种:Dijkstra)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double maxx=1e30,minn,f[2005][2005],c[2005];
int n,m,x,y,s,a[2][2005];
bool b[2005];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&x,&y,&s);
		f[x][y]=f[y][x]=1-(double)(s*0.01);//百分比
	}
	scanf("%d%d",&x,&y);
	for(int i=1;i<=n;++i)
		c[i]=f[x][i];//起始点所能触及的点
	b[x]=1;c[x]=0;
	for(int i=1;i<n;++i)
	{
		minn=-maxx;//因为是看谁大选谁,所以是负的
		int k=0;
		for(int j=1;j<=n;++j)
			if((!b[j])&&(c[j]>minn))
			{
				minn=c[j];
				k=j;
			}
		if(!k)break;
		b[k]=1;
		for(int j=1;j<=n;++j)
			if((c[j]<c[k]*f[k][j])&&(!b[j]))
				c[j]=c[k]*f[k][j];
	}
	printf("%.8lf\n",100/c[y]);//起始点到达终点要100块,所以是100/
	return 0;
}