zoukankan      html  css  js  c++  java
  • Uva 11090 在环中

    题目链接:http://vjudge.net/contest/143318#problem/A

    题意: 求平均权值最小的回路。

    分析:

    平均权值不可能超过最大边,二分查,然后,由于是平均权值,就可以转换一下。

    是否存在平均权值 < mid 的回路: w1 + w2 +.. +wk < k*mid

    (w1-mid) + (w2-mid) +... + (wk-mid)<0;

    只要精度够。 这个式子,就是一个负环,只要改变一下各条边的权值。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 10000;
    
    struct Edge
    {
        int from,to;
        double dist;
    };
    
    struct BellmanFord
    {
        int n, m;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        double d[maxn];
        int p[maxn];
        int cnt[maxn];
    
        void init(int n)
        {
            this->n = n;
            for(int i = 0; i < n; i++) G[i].clear();
            edges.clear();
        }
    
        void AddEdge(int from, int to, double dist)
        {
            edges.push_back((Edge)
            {
                from, to, dist
            });
            m = edges.size();
            G[from].push_back(m-1);
        }
    
        bool negativeCycle()
        {
            queue<int> Q;
            memset(inq, 0, sizeof(inq));
            memset(cnt, 0, sizeof(cnt));
            for(int i = 0; i < n; i++)
            {
                d[i] = 0;
                inq[0] = true;
                Q.push(i);
            }
    
            while(!Q.empty())
            {
                int u = Q.front();
                Q.pop();
                inq[u] = false;
                for(int i = 0; i < G[u].size(); i++)
                {
                    Edge& e = edges[G[u][i]];
                    if(d[e.to] > d[u] + e.dist)
                    {
                        d[e.to] = d[u] + e.dist;
                        p[e.to] = G[u][i];
                        if(!inq[e.to])
                        {
                            Q.push(e.to);
                            inq[e.to] = true;
                            if(++cnt[e.to] > n) return true;
                        }
                    }
                }
            }
            return false;
        }
    };
    
    BellmanFord solver;
    
    bool test(double x)
    {
        for(int i=0; i<solver.m; i++)
        {
            solver.edges[i].dist -= x;
        }
    
        bool ret = solver.negativeCycle();
        for(int i=0; i<solver.m; i++)
        {
            solver.edges[i].dist+=x;
        }
        return ret;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int kase = 1; kase<=t; kase++)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            solver.init(n);
            double ub = 0;
            for(int i=0; i<m; i++)
            {
                int u,v;
                double w;
                scanf("%d%d%lf",&u,&v,&w);
                u--;
                v--;
                ub = max(ub,w);
                solver.AddEdge(u,v,w);
            }
            printf("Case #%d: ",kase);
            if(!test(ub+1)) printf("No cycle found.
    ");
    
            else
            {
                double L = 0,R=ub;
                while(R-L>1e-3)
                {
                    double M = L +(R-L)/2;
    
                    if(test(M)) R = M;
                    else L = M;
    
                }
                printf("%.2f
    ",L);
            }
        }
    
    
        return 0;
    }
  • 相关阅读:
    python学习2(转载)
    python学习1
    第三方授权登录
    新浪微博开发者平台应用申请及配置说明
    新浪微博登录第三方网站实现原理是什么?
    Redis中PipeLine使用
    发送短信验证码的功能开发
    Python celery原理及运行流程
    设置django缓存+验证码图片接口
    编写注册接口
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6111569.html
Copyright © 2011-2022 走看看