最小花费

最小花费

Time Limit:10000MS  Memory Limit:65536K
Total Submit:7 Accepted:1 
Case Time Limit:1000MS

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

Hint

数据规模 
1<=n<=2000

Source



最短 路径 dijkstra算法的应用,数据很大用floyd算法肯定不行。

下面是dijkstra算法AC代码:
#include <iostream>
using namespace std;

const int maxn=2000;
int n,m;
int f[maxn+1][maxn+1];
int s,t;
double dist[maxn+1];
bool hash[maxn+1];
void init()
{
	cin>>n>>m;
	int a,b,c;
	for (int i=0;i<m;i++)
	{
		cin>>a>>b>>c;
		f[a][b]=c;
		f[b][a]=c;
	}
	cin>>s>>t;
}
void dijkstra()
{
	int i,j;
	for(i=1;i<=n;i++)
	{
		if(f[s][i]==0)         //没用通过的方法
		{
			dist[i]=100000.0;
			continue;
		}
		dist[i]=100.0*100/(double)(100-f[s][i]);
		
	}
	dist[s]=100000.0;  hash[s]=true;
	
	for ( i=1;i<n;i++)              //做N-1找s到剩下点的最短路径。
	{
		double min=100000.0;
		int u=0;
		for ( j=1;j<=n;j++)                            //找出身下未添加的点,当中的到s的最短距离。
		{
			if (hash[j]) continue;

			if (min>dist[j]) {min=dist[j];u=j;}
		}

		hash[u]=true;                                        //标记u点添加到找到集合

		for ( j=1;j<=n;j++)
		{
			if (f[u][j]==0) continue;                      

			if (dist[j]>dist[u]*100/(double)(100-f[u][j]))            //如果有一个点能通过u到达j使得原来到达j的距离大于 这条路的距离,那么改变dist[j]的大小

                dist[j]=dist[u]*100/(double)(100-f[u][j]);
		}
	}
	//cout<<dist[t]<<endl;
	printf("%.8lf\n",dist[t]);
	
}
int main()
{
    init();
    dijkstra();
    return 0;
}


你可能感兴趣的:(最小花费)