题意:给出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. centos mysql 操作

    安装mysqlyum -y install mysql-server 修改mysql配置 vi /etc/my.cnf 这里会有很多需要注意的配置项,后面会有专门的笔记 暂时修改一下编码(添加在密码下 ...

  2. ASP.NET 应用程序安全

    原文:http://msdn.microsoft.com/zh-cn/magazine/hh708755.aspx 一.跨站点脚本 简介 XSS 攻击是指将脚本恶意注入用户的浏览会话,这通常在用户不知 ...

  3. Docker初识

    <Docker--从入门到实践>是Docker技术的入门教程,学习时长两天,现整理关键点如下: 1. 什么是Docker? 轻量级操作系统虚拟化解决方案:Go语言实现:下图很好地说明了Do ...

  4. 服务接口API限流 Rate Limit

    一.场景描述 很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统. 也就是面对大流量时,如何进行流量控制? 服务接口的流量 ...

  5. Git 10 周年之际,创始人 Linus Torvalds 访谈

    点这里 十年前的这一周,linux 内核社区面临一个根本性的挑战:他们不再能够使用他们的修复控制系统:BitKeeper,同时其他的软件配置管理遇到了对分布式系统的新需求.Linus Torvalds ...

  6. const以及入栈出栈

    #include "stdafx.h"#include <iostream>using namespace std; class StringStack{ enum{s ...

  7. 李洪强iOS开发之OC面向对象—多态

    OC面向对象—多态 一.基本概念 多态在代码中的体现,即为多种形态,必须要有继承,没有继承就没有多态. 在使用多态是,会进行动态检测,以调用真实的对象方法. 多态在代码中的体现即父类指针指向子类对象. ...

  8. 2016CVTE编程题:兔子藏洞

    兔子藏洞 题目描述 一只兔子藏身于20个圆形排列的洞中(洞从1开始编号),一只狼从x号洞开始找,下次隔一个洞找(及在x+2号洞找),在下次个两个洞找(及在x+5号洞找),以此类推...它找了n次仍然没 ...

  9. 8 simple things that will make you sexy

    8 simple things that will make you sexy8种方法教你不动声色的性感What makes a women sexy? Is it her body? Is it t ...

  10. Shell脚本基础II

    1.shell算术运算 1)加法 r=`expr 4 + 5`(注意! '4' '+' '5' 这三者之间要有空白) r=$[ 4 + 5 ] r=$(( 4 + 5 )) echo $r 2)乘法 ...