P1576 最小花費(fèi)
//https://www.luogu.com.cn/problem/P1576?contestId=96630
//將2轉(zhuǎn)化為0.98
//每次的匯率是相乘的關(guān)系
//邊的邊權(quán)就是匯率的乘機(jī)因?yàn)殄X是越乘越少
//要求最少的錢就是求最大的匯率
#include<bits/stdc++.h>
using namespace std;
int n,m;//n是總?cè)藬?shù),m是邊數(shù)
double G[2001][2001];
int a,b;
bool visited[2001];
double dist[2001];
void Dijsktra(int x)
{
? ?fill(visited+1,visited+1+n,false);
? ?fill(dist+1,dist+1+n,-1);
? ?dist[x]=1.0;//最初的本金就是百分之百不變
? ?for(int i=1;i<=n;i++)
? ?{
? ? ? ?int u=-1;
? ? ? ?double max=-1;
? ? ? ?for(int j=1;j<=n;j++)
? ? ? ?{
? ? ? ? ? ?if(visited[j]==false&&dist[j]>max)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?u=j;
? ? ? ? ? ? ? ?max=dist[j];//找到最大匯率
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?if(u==-1) return;
? ? ? ?visited[u]=true;
? ? ? ?for(int v=1;v<=n;v++)
? ? ? ?{
? ? ? ? ? ?if(visited[v]==false&&G[u][v]!=0&&dist[v]<dist[u]*G[u][v])
? ? ? ? ? ?{
? ? ? ? ? ? ? ?dist[v]=dist[u]*G[u][v];
? ? ? ? ? ?}
? ? ? ?}
? ?}
}
int main()
{
? ?scanf("%d%d",&n,&m);
? ?fill(G[0],G[0]+2001*2001,0);
? ?for(int i=0;i<m;i++)
? ?{
? ? ? ?int u,v;
? ? ? ?double w;
? ? ? ?scanf("%d%d%lf",&u,&v,&w);
? ? ? ?G[u][v]=(100.0-w)/100.0;
? ? ? ?G[v][u]=(100.0-w)/100.0;
? ?}
? ?scanf("%d%d",&a,&b);
? ?Dijsktra(a);
? ?double ans=100.0/dist[b];
? ?printf("%.8f",ans);
}