题意:给出n个点m条边的加权有向图,求平均值最小的回路

自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对

后来看书= =好巧妙的办法, 使用二分法求解,首先记录下来这m条边的最大权值ub

然后可以猜测一个mid,只需要判断是否存在平均值小于mid的回路 假设存在一个包含k条边的回路,回路上各条边的权值分别为w1,w,2,w3,----,wk

那么

w1+w2+w3+----+wk<k*mid

又因为联想到Bellman_Ford可以解决负环,把上式转化一下

(w1-mid)+(w2-mid)+(w3-mid)+----(wk-mid)<0

这样先将每条边w(a,b)转化成为w(a,b)-mid,再判断“新”的图中是否存在负环

自己看的时候有两个不明白的,就是最开始判断的时候为什么要用ub+1,

是因为ub+1是最差的答案了,它能够尽可能的使得每条边负得最多,如果在这种情况下都找不到负环,那么一定不存在负环

然后就是如果在ub+1的条件下能够找到负环,那么就二分查找一步步找出平均值最小的环,直到到达循环退出的精度

代码学习的标程= =

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#define mod=1e9+7; using namespace std; typedef long long LL;
const int INF = 0x7fffffff;
const int maxn=; struct Edge{
int from,to; double dist;
}; struct BellmanFord{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn];
double d[maxn];
int p[maxn];
int cnt[maxn]; void init(int n){
this->n=n;
for(int i=;i<n;i++) G[i].clear();
edges.clear();
} void AddEdges(int from,int to,double dist){
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-);
} bool negativeCycle(){
queue<int> Q;
memset(inq,,sizeof(inq));
memset(cnt,,sizeof(cnt));
for(int i=;i<n;i++) {d[i]=;inq[]=true;Q.push(i);} while(!Q.empty()){
int u=Q.front();Q.pop();
inq[u]=false;
for(int i=;i<G[u].size();i++){
Edge& e=edges[G[u][i]];
if(d[e.to]>d[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
if(!inq[e.to]){
Q.push(e.to);
inq[e.to]=true;
if(++cnt[e.to]>n)
return true;
}
}
}
}
return false;
}
}; BellmanFord solver; bool test(double x){
for(int i=;i<solver.m;i++)
solver.edges[i].dist-=x; bool ret=solver.negativeCycle();
for(int i=;i<solver.m;i++)
solver.edges[i].dist+=x;
return ret;
} int main(){
int T;
scanf("%d",&T);
for(int kase=;kase<=T;kase++){
int n,m;
scanf("%d %d",&n,&m);
solver.init(n);
int ub=;
while(m--){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);u--;v--;ub=max(ub,w);
solver.AddEdges(u,v,w);
}
printf("Case #%d: ",kase);
if(!test(ub+)) printf("No cycle found.\n");
else{
double L=,R=ub;
while(R-L>1e-){
double M=L+(R-L)/;
if(test(M)) R=M;else L=M;
}
printf("%.2lf\n",L);
}
}
return ;
}

UVa 11090 Going in Cycle!!【Bellman_Ford】的更多相关文章

  1. UVA 11090 : Going in Cycle!! 【spfa】

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; const double INF=1e18; ; ; in ...

  2. UVA 11090 - Going in Cycle!!(Bellman-Ford)

    UVA 11090 - Going in Cycle!! option=com_onlinejudge&Itemid=8&page=show_problem&category= ...

  3. UVA - 11090 - Going in Cycle!!(二分+差分约束系统)

    Problem  UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...

  4. 141. Linked List Cycle【easy】

    141. Linked List Cycle[easy] Given a linked list, determine if it has a cycle in it. Follow up:Can y ...

  5. uva 10154 - Weights and Measures【dp】qi

    题意:uva 10154 - Weights and Measures 题意:有一些乌龟有一定的体重和力量,求摞起来的最大高度.力量必须承受其上面包含自己的所有的重量. 分析:先按其能举起来的力量从小 ...

  6. UVa 11090 Going in Cycle!! (Bellman_Ford)

    题意:给定一个加权有向图,求平均权值最小的回路. 析:先十分答案,假设答案是 ans,那么有这么一个回路,w1+w2+w3+...+wk < k*ans,这样就是答案太大,然后移项可得,(w1- ...

  7. UVA 11090 Going in Cycle!!

    要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了. 按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) & ...

  8. UVA 11090 Going in Cycle!! SPFA判断负环+二分

    原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  9. UVA 11090 - Going in Cycle!! SPFA

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

随机推荐

  1. Android Environment FAQ (Frequently Asked Question)

    1.how to find out the Eclipse Version From Eclipse Menu Help ----> About Eclipse It displayed as ...

  2. Unity3D 将 Unity 嵌入WPF中的一些研究笔记

     一. 在 WPF 中使用 WebBrowser,直接打开 WebPlayer.html 以这种方式有一个问题是. 无法在 WebBrowser 的上面 放置其它的控件, 在运行时,都不会显示 . 以 ...

  3. logback日志项目使用方法 - 150205交易模块添加日志信息logback,orderNo订单号为log主键便于跟踪,数字常量化,解决取消支付BUG,弱网络环境原因

    1.项目里面的日志,便于跟踪数据的变更和异常错误信息产生.生产环境的日志级别是INFO,测试环境日志级别DEBUG,如果生产环境的日志级别是DEBUG,虽然方便查询问题,可以看到SQL语句等信息,但是 ...

  4. 【面试题041】和为s的两个数字VS和为s的连续正数序列

    [面试题041]和为s的两个数字VS和为s的连续正数序列 题目一:     输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. ...

  5. FZU2165 v11(带权的重复覆盖)

    题意:有n个boss,m种武器,每种武器选用的时候需要有一定的花费ci,然后这个武器可以消灭掉其中一些BOSS,问你消灭完所有的BOSS,需要的最少花费是多少. 当时比赛的时候,看到这题以为是什么网络 ...

  6. D&F学数据结构系列——AVL树(平衡二叉树)

    AVL树(带有平衡条件的二叉查找树) 定义:一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树. 为什么要使用AVL树(即为什么要给二叉查找树增加平衡条件),已经在我之前的博文中说到过 ...

  7. PHP开发入行真功夫 三扬科技

    前言与目录 PHP开发入行真功夫 前言 PHP开发入行真功夫 目录   第2章 基本语法 2.1.1 判断闰年程序 2.1.2 我们现在能做的…… 2.2.1 PHP的语言概貌 2.2.2 为我们的程 ...

  8. 一个轻量级的3D CSS 库

    JavaScript 3D library 该项目的目的是为了打造轻量级的.实用简单的3D CSS库. Usage使用方法 下载 minified库文件 和 css文件,并将其包含于你的HTML中,就 ...

  9. The first day of HTML

    这是韩顺平老师的<轻松搞定网页设计(html.css.js)>,讲的还凑合,仅作入门.决定还是做好笔记,记录学习的过程,这是HTML的第一天. HTML(HyperText Mark-up ...

  10. Android应用的核心基础

    Android4开发入门经典 之 第二部分:Android应用的核心基础 Android应用中的组件 Application Components Android应用中最主要的组件是: 1:Activ ...