24h購物| | PChome| 登入
2012-12-16 13:32:58| 人氣589| 回應0 | 上一篇 | 下一篇

[UVA][解二][二分+負環] 11090 - Going in Cycle!!

推薦 0 收藏 0 轉貼0 訂閱站台

I I U P C 2 0 0 6

Problem G: Going in Cycle!!

Input: standard input

Output: standard output

 

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

Output for Sample Input

2
2 1
1 2 1
2 2
1 2 2
2 1 3

Case #1: No cycle found.
Case #2: 2.50

 

Problemsetter: Mohammad Tavakoli Ghinani

Alternate Solution: Cho

二分答案,然後將所有邊減去答案,此時檢查是否有存在負環,

以前我都是窮舉點進行 spfa 的迭代,查看是否存在負環 (入隊次數大於 n)

而網路上搜到的是一次放入所有的點去檢查負環,這一點我還必須思考一下。

但我相信是對的。

#include <stdio.h>
#include <vector>
#include <queue>
#define oo 0xfffffff
using namespace std;
struct arc {
    int to, w;
    arc(int x, int y): to(x), w(y) {}
};
vector<arc> g[51];
double dis[51];
int used[51], inq[51];
int negCycle(int n, double m) {
    static int i, tn;
    queue<int> Q;
    for(i = 1; i <= n; i++) {
        dis[i] = 0, used[i] = 1, inq[i] = 0;
        Q.push(i);
    }
    while(!Q.empty()) {
        tn = Q.front(), Q.pop();
        used[tn] = 0;
        for(vector<arc>::iterator it = g[tn].begin();
            it != g[tn].end(); it++) {
            if(dis[it->to] > dis[tn] + it->w - m) {
                dis[it->to] = dis[tn] + it->w - m;
                if(!used[it->to]) {
                    used[it->to] = 1;
                    Q.push(it->to);
                    if(++inq[it->to] > n)
                        return 1;
                }
            }
        }
    }
    return 0;
}
int main() {
    scanf("%*d");
    int n, m, i, a, b, c;
    int cases = 0;
    while(scanf("%d %d", &n, &m) == 2) {
        for(i = 1; i <= n; i++)
            g[i].clear();
        double l = 0, r = 0, mid;
        while(m--) {
            scanf("%d %d %d", &a, &b, &c);
            g[a].push_back(arc(b,c));
            if(c > r)   r = c;
        }
        r += 10;
        printf("Case #%d: ", ++cases);
        if(!negCycle(n, r)) {
            puts("No cycle found.");
            continue;
        }
        while(r - l > 1e-4) {
            mid = (l+r)/2;
            if(negCycle(n, mid))
                r = mid;
            else
                l = mid;
        }
        printf("%.2lf\n", r);
    }
    return 0;
}

台長: Morris
人氣(589) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][bitmask+背包] 10032 - Tug of War
此分類上一篇:[UVA][解一][spfa+窮舉] 11090 - Going in Cycle!!

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文