UVA11090 二分逼近+bf

Going in Cycle!!

You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a weight, which equals to sum of its edges. There are so many cycles in the graph with different weights. In this problem we want to find a cycle with the minimum mean.

Input

The first line of input gives the number of cases, N. N test cases follow. Each one starts with two numbers n and m. m lines follow, each has three positive number a, b, c which means there is an edge from vertex a to b with weight of c.

Output

For each test case output one line containing Case #x: followed by a number that is the lowest mean cycle in graph with 2 digits after decimal place, if there is a cycle. Otherwise print No cycle found..

Constraints

  • n ≤ 50

  • a, b ≤ n

  • c ≤ 10000000

Sample Input

2

2 1

1 2 1

2 2

1 2 2

2 1 3

 

Sample Output

Case #1: No cycle found.

Case #2: 2.5

题意:n个点m条边的有向图,要求平均权值最小的回环

假设最小回环的平均权值是tmp,这样,此图所有权边-tmp构造一个新图,此新图存在一个负环,很容易就得出,此负环就是我们需要的那个平均权值最小的回环。平均权值可以通过二分法得到

下面的代码我以前写过,晚上写了一下,还没有在vj上试过 果然还是挂了哈,排除新图没有负环用了sum_weiths,数太大就超int了,其实应该用max_weight+1就可以了 :smile:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

//#define EdsonLin

#ifdef EdsonLin
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif // EdsonLin

typedef long long ll;
typedef double db;
const ll inf = (1ll)<<60;
const int MAXN = 50;
const int MAXNN = 3e3+10;
const ll MOD = 1000000007;
const db eps = 1e-3;

ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%MOD;a=a*a%MOD;b>>=1;}return ans;}

int n,m;
int first[MAXN];
int top;
struct edge{
    int st;
    int to;
    double dist;
    int next;
}e[MAXNN];
double d[MAXN];
int inq[MAXN];
int cnt[MAXN];

void init(){
    top = 0;
    memset(first,-1,sizeof(first));
}

void addedge(int u,int v,int dist){
    e[top].st = u;
    e[top].to = v;
    e[top].next = first[u];
    e[top].dist = dist;
    first[u] = top++;
}

bool bf(){
    //memset(d,0,sizeof(d));
    //memset(inq,0,sizeof(inq));

    queue<int>Q;
   // cout<<n<<endl;
    for(int i=0;i<n;i++){
        Q.push(i);
        d[i] = inq[i] = cnt[i] = 0;
    }
    inq[0] = 1;
    int u;
    while(!Q.empty()){
        u = Q.front();
        Q.pop();
        inq[u] = 0;
        for(int i=first[u];i!=-1;i=e[i].next){
            int v = e[i].to;
            if(d[v]>d[u]+e[i].dist){
                d[v]=d[u]+e[i].dist;
                if(!inq[v]){
                    Q.push(v);
                    inq[v] = 1;
                    cnt[v]++;
                    #ifdef EdsonLin
                        debug("Edson:%d\n",v);
                    #endif // EdsonLin
                    if(cnt[v]>n)return true;
                }
            }
        }
    }
    return false;
}

bool solve(double d){
    bool sg;
    #ifdef EdsonLin
        debug("Edson:%lf\n",d);
    #endif // EdsonLin
    for(int i=0;i<top;i++)
        e[i].dist -= d;
    sg = bf();
    //cout<<"endl"<<endl;
    for(int i=0;i<top;i++)
        e[i].dist += d;
    return sg;
}

int main(){
    #ifdef EdsonLin
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    int _time_jc = clock();
    #endif // EdsonLin
    int T;
    int mc=0;
    double mmax;
    scanf("%d",&T);
    while(T--){
        init();
        mmax = 0;
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            a--;b--;
            addedge(a,b,c);
            mmax = max(mmax,c*1.0);
        }
        #ifdef EdsonLin
           // debug("Edosn:%lf\n",tmp);
        #endif // Edson

        bool sg = solve(mmax+1);
        if(!sg){
            printf("Case #%d: No cycle found.\n",++mc);
            continue;
        }
        double _e = mmax,_s = 0,_m;
        while(_e-_s>eps){
            _m = (_e+_s)/2;
            if(solve(_m)){
                _e = _m;
            }else{
                _s = _m;
            }
        }
        printf("Case #%d: %.2lf\n",++mc,_s);
    }


    #ifdef EdsonLin
        debug("time: %d\n",int(clock()-_time_jc));
    #endif // EdsonLin

    return 0;
}
View Code

 

posted @ 2016-05-23 20:55  iEdson  阅读(145)  评论(0编辑  收藏  举报