• P1576 最小花费


    题目描述

    在n个人中,某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元。

    输入输出格式

    输入格式:

    第一行输入两个正整数n,m,分别表示总人数和可以互相转账的人的对数。

    以下m行每行输入三个正整数x,y,z,表示标号为x的人和标号为y的人之间互相转账需要扣除z%的手续费 (z<100)。

    最后一行输入两个正整数A,B。数据保证A与B之间可以直接或间接地转账。

    输出格式:

    输出A使得B到账100元最少需要的总费用。精确到小数点后8位。

    输入输出样例

    输入样例#1: 复制
    3 3                                     
    1 2 1
    2 3 2
    1 3 3
    1 3
    
    输出样例#1: 复制
    103.07153164

    说明

    1<=n<=2000,m<=100000

    //这个题看了不下三次了   今天终结了他
    //一直担心精度问题,但是其实把int转成double可以过的
    //建图的时候,让边权=1-w/100,即交完手续费后剩下的钱
    //从B往A跑,dis[v]=min(dis[v],dis[u]/w[i]),这样倒着推回去,赋dis[b]初值为100
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    const int N=2e3+5;
    const int M=1e5+5;
    const int INF=599518803;
     
    int n,m,A,B;
    int x,y;
    double z;
    int head[N],num_edge;
    struct Edge
    {
           int v,nxt;
           double w;
    }edge[M<<1];
    bool inque[N];
    double dis[N];
     
    int read()
    {
           char c=getchar();int num=0;
           for(;!isdigit(c);c=getchar());
           for(;isdigit(c);c=getchar())
                  num=num*10+c-'0';
           return num;
    }
     
    void add_edge(int u,int v,double w)
    {
           edge[++num_edge].v=v;
           edge[num_edge].w=w;
           edge[num_edge].nxt=head[u];
           head[u]=num_edge;
    }
     
    void spfa()
    {
           memset(dis,INF,sizeof(dis));
           //cout<<dis[3];
           queue<int> que;
           dis[A]=100;
           que.push(A);
           int now;
           while(!que.empty())
           {
                  now=que.front(),que.pop();
                  inque[now]=0;
                  for(int i=head[now],v;i;i=edge[i].nxt)
                  {
                         v=edge[i].v;
                         if(dis[v]>dis[now]/edge[i].w)
                         {
                                //printf("AGO: %.8lf       ",dis[v]);
                                dis[v]=dis[now]/edge[i].w;
                                //printf("AFT: %.8lf
    ",dis[v]);
                                if(!inque[v])
                                {
                                       que.push(v);
                                       inque[v]=1;
                                }
                         }
                  }
           }
    }
     
    int main()
    {
           n=read(),m=read();
           for(int i=1;i<=m;++i)
           {
                  x=read(),y=read(),scanf("%lf",&z);
                  z/=100,z=1-z;
                  add_edge(x,y,z);
                  add_edge(y,x,z);
           }
           A=read(),B=read();
           spfa();
           printf("%.8lf",double(dis[B]));
           return 0;
    
    }
  • 相关阅读:
    js字符串加解密
    vue 项目 tab切换共用相同组件不刷新数据问题
    工具使用
    2021前端学习指南
    echart一个框里放三个饼图案例
    jquery的网络引用地址
    上传文件-jq
    异步按照同步顺序执行的function
    js加载顺序
    不安分的项目经理
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8477017.html
Copyright © 2020-2023  润新知