UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)


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, NN test cases follow. Each one starts with two numbers n and mm 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(或者bellmanFord找负环)如果找到,说明平均最小距离比这个值要小,如果没找到,则说明平均最小距离比这个值大。

注意可能是不连通图~

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f
#define eps 1e-6
#define maxn 55
#define MAXN 10005
using namespace std;

int n,m,ans,cnt,sx;
double le,ri,mid,res;
bool vis[maxn];
double dist[maxn];
int head[maxn],num[maxn];
struct Node
{
    int v,next;
    double w;
}edge[MAXN];

void addedge(int u,int v,double w)
{
    cnt++;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt;
}
bool SPFA(int k)
{
    int i,j,nx,v;
    memset(vis,0,sizeof(vis));
    memset(num,0,sizeof(num));
    for(i=1;i<=n;i++) dist[i]=INF;
    sx=k;
    queue<int>q;
    dist[sx]=0;
    vis[sx]=num[sx]=1;
    q.push(sx);
    while(!q.empty())
    {
        nx=q.front();
        vis[nx]=0;
        q.pop();
        for(i=head[nx];i;i=edge[i].next)
        {
            v=edge[i].v;
            if(dist[v]>dist[nx]+edge[i].w-mid)
            {
                dist[v]=dist[nx]+edge[i].w-mid;
                if(!vis[v])
                {
                    num[v]++;
                    if(num[v]>n) return true ;
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return false ;
}
int main()
{
    int i,j,u,v,t,test=0;
    double w;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        cnt=0;
        memset(head,0,sizeof(head));
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%lf",&u,&v,&w);
            addedge(u,v,w);
        }
        le=0; ri=10000005;
        int flag;
        while(ri-le>eps)
        {
            mid=(le+ri)/2.0;
            flag=0;
            for(i=1;i<=n;i++)
            {
                if(SPFA(i))
                {
                    flag=1; break ;
                }
            }
            if(flag) ri=mid;
            else le=mid;
        }
        res=le;
        if(res<=10000001) printf("Case #%d: %.2f\n",++test,res);
        else printf("Case #%d: No cycle found.\n",++test);
    }
    return 0;
}

UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)

时间: 2024-10-06 00:12:20

UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)的相关文章

UVA11090 Going in Cycle!! (二分+SPFA推断有无负权)

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

uva11090 Going in Cycle!! --- 二分+spfa判负环

给一个带权有向图,求其中是否存在环,若存在,输出环上边权的平均值最小的那个的平均值. 点的范围就50,感觉可以很暴力..但显然超时了 感觉方法好巧妙,二分平均值,将所有边权减去二分的那个值,然后spfa判断是否有负环 若有负环,则图中存在的所有环的边权平均值一定比枚举值大 反之则小,要是无论枚举值多大都没有负环,说明图中没有环. #include <iostream> #include <cstring> #include <string> #include <c

poj 3259 bellman最短路判断有无负权回路

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36717   Accepted: 13438 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

UVa 515 - King (差分约束系统 + SPFA求带负权最短路)

下面是差分约束系统的详细介绍,以及解决方法~ 摘抄自 xuezhongfenfei(他好像也是转的....) 差分约束系统 X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5 X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 不等式组(1) 全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就可以化成小于等于).这样的不等式组

UVA11090 Going in Cycle!! 【SPFA】

题意:求一个无向图的边权平均值最小的环 思路:假设环中Σwi/t<ans 那变形一下就是Σwi<ans*t → Σ(wi-ans)< 0 这样就可以二分答案做了 #include <stdio.h> #include <iostream> #include<queue> #include <string.h> #include <algorithm> #define maxn 90000 #define esp 0.000000

SPFA 求带负权的单源最短路

int spfa_bfs(int s) { ///s表示起点: queue <int> q; memset(d,0x3f,sizeof(d)); ///d数组中存下的就是最短路径(存在的话) d[s] = 0; memset(c,0,sizeof(c));///c数组表示的是某一个节点的入队次数 memset(vis,0,sizeof(vis));///一如既往的标记数组 q.push(s); vis[s] = 1; c[s] = 1; ///顶点入队vis要做标记,另外要统计顶点的入队次数

POJ 3259 Wormholes【最短路/SPFA判断负环模板】

农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径,W(1≤W≤200)个虫洞.FJ作为一个狂热的时间旅行的爱好者,他要做到以下几点:开始在一个区域,通过一些路径和虫洞旅行,他要回到最开时出发的那个区域出发前的时间.也许他就能遇到自己了:).为了帮助FJ找出这是否是可以或不可以,他会为你提供F个农场的完整的映射到(1≤F≤5).所有的路径所花时间都

[Usaco2007 Dec][BZOJ1690] 奶牛的旅行|分数规划|二分|SPFA

1690: [Usaco2007 Dec]奶牛的旅行 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 700  Solved: 363[Submit][Status][Discuss] Description 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城市地图,上面标注了城市中所有L(2 <= L <= 1000)座标志

bzoj1690:[Usaco2007 Dec]奶牛的旅行 (分数规划 &amp;&amp; 二分 &amp;&amp; spfa)

用dfs优化的spfa判环很快啦 分数规划的题目啦 二分寻找最优值,用spfa判断能不能使 Σ(mid * t - p) > 0 最优的情况只能有一个环 因为如果有两个环,两个环都可以作为奶牛的行程,如果两个环单独计算的结果不一样,那么两个环中比值更大的才是最优解,如果结果一样,多算一个环就没有意义了. 代码如下 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespa