zoukankan      html  css  js  c++  java
  • TTTTTTTTTTTT CF 653D 送邮递员

    链接:给一张n个点m条带权边的有向图,有x个人从起点出发到终点,每个人带的都带相同重量的货物, 
    规定一条边最多能经过其上权的重量的货物,问最多能带多重的货物? 
    2 ≤ n ≤ 50, 1 ≤ m ≤ 500, 1 ≤ x ≤ 100 000

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const ll inf = 1e16;
    const double pi=acos(-1);
    const int mod=100000000;
    
    struct edge{
      int to;
      ll c;
      int rev;
    };//注意顺序关系与(edge){}对应
    
    vector<edge> G[55];
    vector<edge> F[55];
    int level[55],iter[55];
    int n,m,x,u,v,c;
    
    
    void bfs(int s)
    {
         queue<int> q;
         q.push(s);
         level[s]=1;
         while(q.size())
         {
             int u=q.front();q.pop();
             for(int i=0;i<G[u].size();i++)
             {
                 edge e=G[u][i];
                 if(e.c>0&&level[e.to]==-1)
                 {
                     level[e.to]=level[u]+1;
                     q.push(e.to);
                 }
             }
         }
    }
    
    double dfs(int s,int t,double minn)
    {
         if(s==t) return minn;
         for(int &i=iter[s];i<G[s].size();i++)
         {
             edge &e=G[s][i];
             if(e.c>0&&level[e.to]>level[s])
             {
                int d=dfs(e.to,t,min((double)minn,(double)e.c));
                if(d>0)
                {
                    e.c-=d;
                    G[e.to][e.rev].c+=d;
                     return d;
                 }
             }
         }
         return 0;
    }
    
    bool ok(double mid)
    {
        for(int i=1;i<=n;i++) G[i].clear();
        for(int i=1;i<=n;i++)
            for(int j=0;j<F[i].size();j++)
            {
                G[i].push_back(F[i][j]);
                G[i][j].c=(ll)(F[i][j].c/mid);//精度很重要
            }
        double ans=0,temp;
        for(;;)
        {
            MM(level,-1);
            bfs(1);
            if(level[n]<0) break;
            MM(iter,0);
            while((temp=dfs(1,n,inf))>0)
                ans+=temp;
        }
        return ans>=x;
    }
    
    int main()
    {
        double l,r;
        while(~scanf("%d %d %d",&n,&m,&x))
        {
               for(int i=1;i<=n;i++)  F[i].clear();
               l=0;r=0;
               for(int i=1;i<=m;i++)
                     {
                         scanf("%d %d %d",&u,&v,&c);
                         F[u].push_back((edge){v,c,F[v].size()});
                         F[v].push_back((edge){u,0,F[u].size()-1});
                         r=max(r,(double)c);//库里的max参数
                     }
               for(int i=1;i<=200;i++)
               {
                   double mid=(l+r)/2;
                   if(ok(mid)) l=mid;
                   else r=mid;
               }
               printf("%.10f
    ",r*x);
        }
        return 0;
    }
    

     分析:这道题精度卡的很恶心,但是用double的话这道题就没什么问题了;

    参考资料 深刻的领会了long long的强大,,double的有效位数是15-17位,但是能表示的范围

    可以达到10^308,,因为是科学计数法,,,double是 1.1234567890123456E指数这种表示的

  • 相关阅读:
    微信小程序右上角胶囊的位置
    NLP复习大纲
    网站收藏
    css中如何调整插入背景图片的大小
    禁止Power Apps Canvas用户通过SharePoint Online UI界面访问站点list
    c++ vector基本知识
    c++ map基本知识
    c++ string操作
    python学习笔记30:操作excel
    c++, 如何run一个c++程序
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5397251.html
Copyright © 2011-2022 走看看