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

思路:一开始乖乖的打了个Dijkstra记录路径然后慢慢求最后才发现好扯淡也就能过个样例

   正确做法是求出每个边的权重然后直接暴力

   注意因为有除法的存在所以大于号小于号可能和平常的Dijkstra相反

0分代码

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 int map[3000][3000];
 6 double money=100;
 7 int dis[3000];
 8 int maxn=0x7fffff;
 9 int pass[3000];
10 int vis[3000];
11 int n,m;
12 int ans[1001];
13 void print(int bg,int ed)
14 {
15     
16     int now=1;
17     ans[now]=ed;
18     now++;
19     int tmp=pass[bg];
20     while(tmp!=ed&&tmp!=0)
21     {
22         ans[now]=tmp;
23         now++;
24         tmp=pass[tmp];
25     }
26     ans[now]=bg;
27     int qq=ed;
28     for(int i=2;i<=now;i++)
29     {
30         money=money/((double)(100-map[ans[i-1]][ans[i]])/100);
31     }
32     printf("%.8lf",money);
33 }
34 void Dijkstra(int p)
35 {
36     memset(dis,0x7f,sizeof(dis));
37     vis[p]=1;
38     for(int i=1;i<=n;i++)
39     {
40         dis[i]=map[p][i];
41     }
42     for(int i=1;i<=n;i++)
43     {
44         int minn=maxn;
45         int k;
46         for(int j=1;j<=n;j++)
47         {
48             if(vis[j]==0&&dis[j]<minn)
49             {
50                 minn=dis[j];
51                 k=j;
52             }
53         }
54         vis[k]=1;
55         for(int j=1;j<=n;j++)
56         {
57             if(dis[j]>dis[k]+map[k][j])
58             {
59                 dis[j]=dis[k]+map[k][j];
60                 pass[j]=k;
61             }
62         }
63     }
64 }
65 int main()
66 {
67     memset(map,0x7f,sizeof(map));    
68     scanf("%d%d",&n,&m);
69     for(int i=1;i<=n;i++)
70     {
71         int x,y,z;
72         scanf("%d%d%d",&x,&y,&z);
73         map[x][y]=z;
74         map[y][x]=z;
75     }
76     int a,b;
77     scanf("%d%d",&a,&b);
78     Dijkstra(b);
79     print(b,a);
80     return 0;
81 }

AC代码

 1 #include<iostream>
 2 #define MAXN 2001
 3 #define inf 99999
 4 using namespace std;
 5 int N,M,A,B;
 6 double m[MAXN][MAXN];
 7 int main()
 8 {
 9     int i,j;
10     cin>>N>>M;
11     cout.setf(ios::fixed);
12     for (i=0;i<N;i++)
13         for (j=0;j<N;j++)
14             m[i][j]=1/inf;
15     for (i=0;i<M;i++)
16     {
17         int x,y,t;
18         cin>>x>>y>>t;
19         x--; y--;
20         m[x][y]=m[y][x]=1-(t/100.0);        //exchange to weight
21     }
22     cin>>A>>B;
23     A--; B--;
24     //dijkstra
25     double dis[MAXN];                            //dis i:money needed to trans 100 to i
26     bool book[MAXN];
27     book[B]=true;
28     for (i=0;i<N;i++)
29     {
30         dis[i]=100/m[B][i];                    //init dis[]
31         book[i]=false;                            //init book[]
32     }
33     for (j=0;j<N;j++)
34     {
35         int nmin;
36         double min=inf;
37         for (i=0;i<N;i++)
38             if (dis[i]<min&&!book[i])
39             {
40                 nmin=i;
41                 min=dis[nmin];                    //find #min->nmin
42             }
43         book[nmin]=true;                        //record in book[]
44         for (i=0;i<N;i++)
45             if (min/m[nmin][i]<dis[i]&&!book[i])        //relax
46                 dis[i]=min/m[nmin][i];
47     }
48     cout.precision(8);
49     cout<<dis[A];
50     return 0;
51 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个爱吃西瓜的程序员

每天学习一点儿算法--散列表

在之前我们已经学过了二分查找和简单查找,我们知道二分查找的运行时间为O(㏒ n), 简单查找的运行时间为O(n)。除此之外,还有没有更快的查找算法呢? 可能有人...

30160
来自专栏灯塔大数据

灯塔原创 | 封建迷信撞上人工智能,AI也许就要取代算命先生

导读:每天我们打开电脑,头条新闻都充斥着人工智能和大数据算法最新突破的信息,可是何曾想到,AI已经悄悄地离开城市中心的高楼大厦,不再满足于现代化行业领域的它,踏...

39060
来自专栏灯塔大数据

每周学点大数据 | No.49 维基百科的策略中体现的“众包算法”的思想

No.48期 众包的定义 Mr. 王:平常遇到不知道的概念或者名词,你一般会怎么办? 小可:有维基百科啊,我去查一查就知道了。对于一个名词,维基百科能给出很多...

35040
来自专栏一个爱吃西瓜的程序员

每天学习一点儿算法--快速排序

快速排序是一种常用的优雅的排序算法,它使用分而治之的策略。 那么分而治之(D&C)是一种怎样的策略呢? 分而治之 分而治之(D&C)的要点只有两个: 找出简单...

33040
来自专栏机器学习算法与Python学习

机器学习(2)之过拟合与欠拟合

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 过拟合与欠拟合 上一篇(机器学习(1...

40450
来自专栏Albert陈凯

理解zookeeper选举机制

zookeeper集群 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点...

99050
来自专栏机器学习算法与Python学习

机器学习(1)之入门概念

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 机器学习是什么 机器学习是什么?实际...

303100
来自专栏Albert陈凯

CRC32算法冲突概率测试和分析

最近因为某个业务需要用到CRC32算法,但业务又不能容忍重复的数值出现,于是自然就想了解一下CRC32算法的冲突概率(或者叫碰撞概率)。 本以为这种问题应该很多...

71990
来自专栏灯塔大数据

塔说 | 麦克阿瑟天才奖得主解码计算机视觉“原罪”:AI 如何认识人类世界

导读:麦克阿瑟“天才奖”获得者Trevor Paglen训练AI算法,他的展览项目“看不见的图像的研究”(A Study of Invisible Images...

35790
来自专栏一个爱吃西瓜的程序员

每天学习一点儿算法--广度优先搜索

广度优先搜索(BFS)是我们学的第一种图算法,它可以让你找出两样东西之间的最短距离。 这里提到了一个新的概念:图, 那什么是图呢? 图简介 图用于模拟不同的东...

35840

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励