zoukankan      html  css  js  c++  java
  • 洛谷P1576||最小花费||dijkstra||双向建边!!

     

    题目描述

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

    数据范围

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

    思路分析

    可以把每个人看成是一个点,那么题目描述的问题就是使得A->B的花费最少,即两点间的最短路问题,这里我们采用dijkstra算法。

    由于m<=100000,故我们采用链式前向星进行存储图,每次找到一个距离原点最近并且没有被访问过的点后,遍历连接此点的每一条边,更新其连接节点的花费

    代码(我把dijkstra分为两部分,这样虽然效率低,但是对于我来说思路更清晰些)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<iomanip>
    #define N 300010
    #define MAXX 1e7+10
    #define MINN -1e7+10
    using namespace std;
    
    
    struct road
    {
        int starts,ends,vals;
    }ro[N];
    double firsts[N],NEXT[N];
    int len=0;
    int n,m,A,B;
    double dis[N];
    double inputnum[N][4];
    void insert(int  xx,int  yy,int  zz)
    {
        len++;
        ro[len].starts=xx;ro[len].ends=yy;ro[len].vals=zz;
        NEXT[len]=firsts[xx];firsts[xx]=len;
    }
    
    void init()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            int aa,bb,cc;
            cin>>aa>>bb>>cc;
            insert(aa,bb,cc);
            insert(bb,aa,cc);
        }
        cin>>A>>B;
    }
    bool flag[N];
    inline void pre(){    for(int i=1;i<=n;i++)   dis[i]=MAXX;}
    inline void dijkstra1(int st,double vv)//单源点dijkstra
    {
    
        for(int i=firsts[st];i;i=NEXT[i])   //如果出度的权值小于当前dis数组的权值,那么就更新dis数组
        {
            if(dis[st]/(1-ro[i].vals*0.01)<dis[ro[i].ends])
            {
                dis[ro[i].ends]=dis[st]/(1-ro[i].vals*0.01);
            }
        }
    
    }
    
    void dijkstra()
    {
        pre();
        dis[A]=100;
        for(int i=firsts[A];i;i=NEXT[i])
        {
            dis[ro[i].ends]=dis[A]/(1-ro[i].vals*0.01);
        }
       // for(int i=1;i<=n;i++)   //cout<<i<<' '<<dis[i]<<' ';  //cout<<endl;
        for(int j=1;j<=n;j++){
            double minn=999999999;int temp;
            for(int i=1;i<=n;i++){
                if(i==A)    continue;
                if(flag[i]==1)  continue;
                if(dis[i]<minn)
                {
                    temp=i;minn=dis[i];
                    ////cout<<dis[i]<<' '<<minn<<endl;
                }
            }
            flag[temp]=1;
            dijkstra1(temp,minn);
    
        }
    }
    
    void debug_output()
    {
        for(int i=1;i<=len;i++)
            cout<<ro[i].starts<<' '<<ro[i].ends<<' '<<ro[i].vals<<' '<<NEXT[i]<<' '<<firsts[ro[i].starts]<<endl;
    
    }
    int main()
    {
       // freopen("a.in","r",stdin);
       // freopen("a.out","w",stdout);
        init();
        //debug_output();
        dijkstra();
       cout<<fixed<<setprecision(8);
      // for(int i=1;i<=n;i++)
       cout<<dis[B]<<endl;
        return 0;
    }

  • 相关阅读:
    Tensorflow Tutorial 2: image classifier using convolutional neural network Part-1(译)
    TensorFlow Tutorial: Practical TensorFlow lesson for quick learners
    TensorFlow Tutorial: Practical TensorFlow lesson for quick learners
    Builder Pattern(译)
    Mysql锁机制
    Monitorenter
    非静态内部类
    ConcurrentModificationException
    Http2.0协议
    Docker化 springboot项目
  • 原文地址:https://www.cnblogs.com/supersumax/p/9498629.html
Copyright © 2011-2022 走看看