UVA 11090 Going in Cycle!!

要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了。

按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) < 0,将每条边减去ave看是否存在负权回路,然后不断二分,由于保留两位小数,所以至少二分log(10^7)= 30次。

代码:

#include <iostream>
#include <sstream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define  esp 1e-6
#define  pi acos(-1.0)
#define  pb push_back
#define  lson l, m, rt<<1
#define  rson m+1, r, rt<<1|1
#define  mp(a, b) make_pair((a), (b))
#define  in  freopen("in.txt", "r", stdin);
#define  out freopen("out.txt", "w", stdout);
#define  print(a) printf("%d\n",(a));
#define  bug puts("********))))))");
#define  stop  system("pause");
#define  Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define  inf 0x0f0f0f0f

using namespace std;
typedef long long  LL;
typedef vector<int> VI;
typedef pair<int,int> pii;
typedef vector<pii> VII;
typedef vector<pii, int> VIII;
typedef VI:: iterator IT;
const int maxn = 100;

struct Edge
{
    int from, to;
    double dist;
};

struct Bellman_Ford
{
    int n, m;
    vector<Edge> edges;
    VI G[maxn];
    double d[maxn];
    int p[maxn];
    int inq[maxn];
    int cnt[maxn];

    void init(int n)
    {
        this->n = n;
        for(int i = 0; i < n; i++)
        {
            G[i].clear();
        }
        edges.clear();
    }

    void add(int from, int to, double dist)
    {
        edges.pb((Edge)
        {
            from, to, dist
        });
        m = edges.size();
        G[from].pb(m-1);
    }
    bool negativeCircle(double L)
    {
        memset(cnt, 0, sizeof(cnt));
        memset(inq, 0, sizeof(inq));
        queue<int> q;

        for(int i = 0; i < n; i++)
        {
            d[i] = 0;
            inq[0] = 1;
            q.push(i);
        }
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            inq[u] = 0;
            for(int i = 0; i < G[u].size(); i++)
            {
                Edge &e = edges[G[u][i]];
                if(d[e.to] > d[u] + e.dist - L)
                {
                    d[e.to] = d[u] + e.dist - L;
                    if(!inq[e.to])
                    {
                        q.push(e.to);
                        inq[e.to] = 1;
                    }
                    if(++cnt[e.to] > n)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }
} solver;

int main(void)
{

    int T;
    for(int t = scanf("%d", &T); t <= T; t++)
    {
        printf("Case #%d: ", t);
        int n, m;
        scanf("%d%d", &n, &m);
        solver.init(n);
        double ans = inf + 100;

        double l = (double)inf*10, r = 0;
        while(m--)
        {
            int u, v;
            double w;
            scanf("%d%d%lf", &u, &v, &w);
            u--, v--;
            if(u == v)
                ans = min(ans, w);
            solver.add(u, v, w);
            l = min(l, w);
            r = max(r, w);
        }
        int flag= 0;
        double mid = (l+r)/2;
        for(int i = 0; i < 30; i++)
        {
            if(solver.negativeCircle(mid))
                flag = 1, r = mid-0.001;
            else l = mid+0.001;
            mid = (l+r)/2;
        }
        if(flag)
            printf("%.2f\n", min(ans, mid));
            else if(ans < inf)
                printf("%.2f\n", ans);
        else puts("No cycle found.");
    }
    return 0;
}

posted on 2013-11-02 19:12  rootial  阅读(338)  评论(0编辑  收藏  举报

导航