zoukankan      html  css  js  c++  java
  • 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 }
    View Code

    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 }
    View Code
  • 相关阅读:
    单链表的实现C语言版
    顺序表的基本方法实现C语言版
    算法
    Redis
    Linux安装python3.6.1
    Markdown 基本使用手册
    设计Django个人博客网站
    RabbitMQ消息队列
    堡垒机 Paramiko 模块
    进程、线程、协程总结
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6686393.html
Copyright © 2011-2022 走看看