• P1576 最小花费 洛谷


    https://www.luogu.org/problem/show?pid=1576

    题目背景

    题目描述

    在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

    设得到钱的一方的钱为x,则发钱一方的钱至少为x/(1-z),可以与处理每两个人的间的交易损失,跑一边最大路(注意是乗,意会去~~)

    ans=100/dis[b]了。。

    时隔多月,发现自己好像快看不懂Dijkstra了、、、

    加一个SPFA

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 #define N 2005
     8 using namespace std;
     9 double dis[N],z;
    10 int n,m,x,y,s,t,tot,head[N];
    11 struct Edge
    12 {
    13     int to,from,next;
    14     double dis;
    15 }edge[N*N];
    16 int read()
    17 {
    18     int x=0,f=1; char ch=getchar();
    19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    20     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    21     return x*f;
    22 }
    23 int add(int x,int y,double z)
    24 {
    25     tot++;
    26     edge[tot].to=y;
    27     edge[tot].dis=z;
    28     edge[tot].next=head[x];
    29     head[x]=tot;
    30 }
    31 void spfa(int s)
    32 {
    33     queue<int>q; bool vis[N];
    34     for(int i=1;i<=n;i++) vis[i]=false;
    35     q.push(s),vis[s]=true,dis[s]=1;
    36     while(!q.empty())
    37     {
    38         int x=q.front();q.pop();
    39         for(int i=head[x];i;i=edge[i].next)
    40         {
    41             int t=edge[i].to;
    42             if(dis[t]<dis[x]*edge[i].dis) 
    43             {
    44                 dis[t]=dis[x]*edge[i].dis;
    45                 if(!vis[t])
    46                 {
    47                     q.push(t);
    48                     vis[t]=true;
    49                 }
    50             }
    51         }
    52         vis[x]=false;
    53     }
    54 }
    55 int main()
    56 {
    57     n=read(),m=read();
    58     for(int i=1;i<=m;i++)
    59     {
    60         x=read(),y=read();
    61         scanf("%lf",&z);
    62         z=(100-z)/100;
    63         add(x,y,z);add(y,x,z);
    64     }
    65     s=read(),t=read();
    66     spfa(s);
    67     double ans=100/dis[t];
    68     printf("%.8lf",ans);
    69 }
    View Code
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define maxn 1e20
    
    using namespace std;
    
    int n,m,a,b,k,x,y,z;
    double val[2005][2005],w[2005],minn;
    bool vis[2005];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            scanf("%lf",&val[x][y]);
            val[x][y]=(100-val[x][y])/100;
            val[y][x]=val[x][y];
        }
        scanf("%d%d",&a,&b);
        for(int i=1;i<=n;i++)
            w[i]=val[a][i];
        w[a]=1;
        vis[a]=1;
        for(int i=1;i<n;i++)
        {
            minn=0;
            for(int j=1;j<=n;j++)
                if(!vis[j]&&minn<w[j])
                {
                    minn=w[j];
                    k=j;
                }
            vis[k]=1;
            if(k==b)    break;
            for(int j=1;j<=n;j++)
                if(!vis[j]&&w[j]<val[k][j]*w[k])
                    w[j]=val[k][j]*w[k];
        }
        printf("%.8lf",100/w[b]);
        return 0;
    }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    菜鸟也为Git疯狂
    C#实现简单的栈和队列
    Entity Framework模型在领域驱动设计界定上下文中的应用
    SQL 关于使用CTE
    《高效程序员的45个习惯》读书笔记
    开源.NET下的XML数据库介绍及入门
    openkm开发环境搭建过程
    ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇
    《Clean Code》Learning
    网络抓包工具 Network Monitor使用方法 Fiddler使用方法
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6504297.html
Copyright © 2020-2023  润新知