UVa11090 Going in Cycle!!

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34650

【思路】

二分+SPFA。

二分平均值mid,如果有平均值小于mid的情况我们就缩小猜测值否则增大猜测值。如何判定?如果有平均值小于mid 则有:w1-mid+w2-mid+w3-mid+…<0 即将各条边权减mid后图中存在负圈,SPFA判负圈即可。

需要注意把int修改为double

【代码】

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 const int maxn = 100+10;
 8 const double INF=1e10;
 9 struct Edge{
10     int v,next;
11     double w;
12 }e[maxn*maxn];
13 int en,front[maxn];
14
15 int n,m;
16
17 inline void AddEdge(int u,int v,double w) {
18     en++; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en;
19 }
20
21 bool SPFA_NC() {
22     int inq[maxn],cnt[maxn];
23     double d[maxn];
24     queue<int> q;
25     memset(cnt,0,sizeof(cnt));
26     memset(inq,0,sizeof(inq));
27     //添加一个超级源节点
28     for(int s=1;s<=n;s++)
29     {
30       d[s]=0; inq[s]=1; q.push(s);
31     }
32     while(!q.empty()) {
33         int u=q.front(); q.pop(); inq[u]=0;
34         for(int i=front[u];i>=0;i=e[i].next) {
35             int v=e[i].v; double w=e[i].w;
36             if(d[v]>d[u]+w) {
37                 d[v]=d[u]+w;
38                 if(!inq[v]) {
39                     inq[v]=1;
40                     q.push(v);
41                     if(++cnt[v]>n+1) return true;
42                 }
43             }
44         }
45     }
46     return false;
47 }
48
49 inline void init() {
50     en=0;
51     memset(front,-1,sizeof(front));
52 }
53
54 bool can(double x) {
55     for(int i=1;i<=en;i++) e[i].w-=x;
56     bool ans=SPFA_NC();
57     for(int i=1;i<=en;i++) e[i].w+=x;
58     return ans;
59 }
60
61 int main() {
62     int T;
63     scanf("%d",&T);
64     for(int kase=1;kase<=T;kase++) {
65         init();
66         scanf("%d%d",&n,&m);
67         double L=0,R=0;
68         int u,v; double w;
69         for(int i=0;i<m;i++) {
70             scanf("%d%d%lf",&u,&v,&w);
71             AddEdge(u,v,w);
72             if(w>R) R=w;
73         }
74         printf("Case #%d: ",kase);
75         if(!can(R+1)) printf("No cycle found.\n");
76         else
77         {
78            while(R-L>1e-3) {
79                 double M=L+(R-L)/2;
80                 if(can(M)) R=M;  //存在平均值小于mid的回路 则缩小猜测值
81                   else L=M;
82            }
83            printf("%.2lf\n",L);
84         }
85     }
86     return 0;
87 }
时间: 2024-10-19 12:37:57

UVa11090 Going in Cycle!!的相关文章

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

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

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负环]

https://vjudge.net/problem/UVA-11090 平均权值最小的回路 为后面的做个铺垫 二分最小值,每条边权减去他,有负环说明有的回路平均权值小于他 spfa求负环的时候可以先把所有点加到队列里,d[i]=0 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N=55;

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

UVA-11090 Going in Cycle!! (平均值最大回路)

题目大意:一个n个点,m条无向边的图,求出平均权值最小的回路. 题目分析:二分枚举平均值mid,只需判断是否存在平均值小于mid的回路,即判断是否有sum(wi)<mid*k (1≤i≤k),只需判断是否有sum(wi-mid)<0,只需将边权值减去mid后,判断是否存在负环. 代码如下: # include<iostream> # include<cstdio> # include<queue> # include<vector> # incl

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

[leedcode 142] Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up:Can you solve it without using extra space? 因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(a+b) = a+b+c+b,可以得到a=c(这个结论很重要!).  我们已经得到了结论a=c,那么让两个指针分别从X

jQuery图片切换插件jquery.cycle.js

Cycle是一个很棒的jQuery图片切换插件,提供了很好的功能来帮助大家更简单的使用插件的幻灯功能 下载cycle插件并引入,此时,注意把引入它的代码放在引入jQuery主文件之后. <head> <script type="text/javascript" src="js/jquery-1.8.0.min.js"></script> <script type="text/javascript" src

Gartner&#39;s Hype Cycle for Emerging Technologies

2012 2013 2014 2015 2016 Gartner's Hype Cycle for Emerging Technologies