题目链接http://vjudge.net/problem/viewProblem.action?id=34650

题目大意:

给定n个点m条边的加权有向图,求平均权值最小的回路。
平均权值=路径权值之和/路径边数

我们可以通过找到他其中的最小和最大值,然后通过二分不断查找满足的点,然后尽可能的取到它的最大值,因为这里保留两位有效小数,所以设立

while(la-st>0.001)即可

找到一个满足的值是要建立在图上的每一条线段减去这个值后便能得到一个负圈,我们通常用spfa判负圈。

这个spfa只是用来作判断并不是算最短路径,为了防止出现多个连通分量,你只从一个点开始可能遍历整个图,所以最开始就把节点全放入队列中,dp[i]的

值全设定为0,如果出现负圈,则会为了找到最小值一直循环更新,我们用cnt[]数组,当某个点被访问了n次以上时,说明出现了负圈。

具体spfa函数如下所示:

bool spfa()
{
for(int i=;i<=n;i++) cnt[i]=,visit[i]=;
visit[]=;
queue<int> q;
for(int i=;i<=n;i++) q.push(i),dp[i]=;
while(!q.empty()){
int u=q.front();
visit[u]=;
q.pop();
for(int i=first[u];i!=-;i=path[i].next){
if(dp[path[i].y]>dp[u]+path[i].d){
dp[path[i].y]=dp[u]+path[i].d;
if(!visit[path[i].y]) {
q.push(path[i].y);
if(++cnt[path[i].y]>n) return true;
}
}
}
}
return false;
}

我们每次减去一个要找到的mid值,那我们一定要在判断结束后给它加回来以免下次判断出意外

总代码如下:

 #include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define N 52
int first[N],visit[N],k,cnt[N],n;
double dp[N],maxn,minn;
struct Path{
int y,next;
double d;
}path[]; void add(int a,int b,double c)
{
path[k].y=b,path[k].d=c,path[k].next=first[a];
first[a]=k++;
} bool spfa()
{
for(int i=;i<=n;i++) cnt[i]=,visit[i]=;
visit[]=;
queue<int> q;
for(int i=;i<=n;i++) q.push(i),dp[i]=;
while(!q.empty()){
int u=q.front();
visit[u]=;
q.pop();
for(int i=first[u];i!=-;i=path[i].next){
if(dp[path[i].y]>dp[u]+path[i].d){
dp[path[i].y]=dp[u]+path[i].d;
if(!visit[path[i].y]) {
q.push(path[i].y);
if(++cnt[path[i].y]>n) return true;
}
}
}
}
return false;
} bool findMid(double mid)
{
for(int i=;i<k;i++) path[i].d-=mid;
bool temp=spfa();
for(int i=;i<k;i++) path[i].d+=mid;
return temp;
} int main()
{
int T,m,a,b;
double c,st,la,mid,ans=-;
scanf("%d",&T);
for(int j=;j<=T;j++){
memset(first,-,sizeof(first));
scanf("%d%d",&n,&m);
k=;
maxn=,minn=;
for(int i=;i<m;i++)
{
scanf("%d%d%lf",&a,&b,&c);
add(a,b,c);
maxn=max(maxn,c);
minn=min(minn,c);
}
st=minn-,la=maxn;
printf("Case #%d: ",j);
if(!findMid(la+)){printf("No cycle found.\n");continue;}
while(la-st>0.001){
mid=st+(la-st)/;
if(findMid(mid)) la=mid;
else ans=mid,st=mid;
}
printf("%.2f\n",ans);
}
return ;
}

UVA 11090 判负圈问题的更多相关文章

  1. LightOJ-1074(SPFA判负圈+Bellman-Ford算法)

    Extended Traffic LightOJ-1074 这题因为涉及到减法和三次方,所以可能会出现负圈. 这里使用的算法叫做SPFA算法,这个可以用来判负圈和求解最短路.Bellman-Ford算 ...

  2. BZOJ 1486: [HNOI2009]最小圈( 二分答案 + dfs判负圈 )

    二分答案m, 然后全部边权减掉m, 假如存在负圈, 那么说明有平均值更小的圈存在. 负圈用dfs判断. ------------------------------------------------ ...

  3. POJ-3259(最短路+Bellman-Ford算法判负圈)

    Wormholes POJ-3259 这题是最短路问题中判断是否存在负圈的模板题. 判断负圈的一个关键就是理解:如果在图中不存在从s可达的负圈,最短路径不会经过一个顶点两次.while循环最多执行v- ...

  4. [poj3259]Wormholes(spfa判负环)

    题意:有向图判负环. 解题关键:spfa算法+hash判负圈. spfa判断负环:若一个点入队次数大于节点数,则存在负环.  两点间如果有最短路,那么每个结点最多经过一次,这条路不超过$n-1$条边. ...

  5. 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)

    layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: ...

  6. UVA 11090 Going in Cycle!!(二分答案+判负环)

    在加权有向图中求平均权值最小的回路. 一上手没有思路,看到“回路”,第一想法就是找连通分量,可又是加权图,没什么好思路,那就转换题意:由求回路权值->判负环,求最小值->常用二分答案. 二 ...

  7. UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)

    题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路. 思路:使用二分法求解.对于每个枚举值mid,推断每条边权值减去mid后有无负圈就可以. #include<cstdio> # ...

  8. 【dfs判负环】BZOJ1489: [HNOI2009]最小圈

    Description 找出一个平均边权最小的圈. Solution 经典问题,二分答案判断有无负环. 但数据范围大,普通spfa会超时,于是用dfs判负环(快多了). 思路是dis设为0,枚举每个点 ...

  9. [HNOI2009]最小圈 分数规划 spfa判负环

    [HNOI2009]最小圈 分数规划 spfa判负环 题面 思路难,代码简单. 题目求圈上最小平均值,问题可看为一个0/1规划问题,每个边有\(a[i],b[i]\)两个属性,\(a[i]=w(u,v ...

随机推荐

  1. [已读]编写可维护的javascript

    13年4月份出版,作者是大名鼎鼎的Zakas,他的另两本书<javascript高级程序设计>与<高性能javascript>你一定听过或者读过. 这本书重点讲了编码风格和编码 ...

  2. MongoDB学习笔记~监控Http请求的消息链

    在微服务架构里,你的一个任务可以需要经过多次中转,去多个接口获取数据,而在这个过程中,出现问题后的解决就成了一个大难点,你无法定位它的问题,这时,大叔的分布式消息树就出现了,费话不多说,主要看一下实现 ...

  3. 在线编译器Coding Ground

    http://www.tutorialspoint.com/codingground.htm Free Online IDE and Terminal - Edit, Compile, Execute ...

  4. Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bhive.session.id%7D_resources

    原因:环境变量设置问题 <property>    <name>Hive.exec.local.scratchdir</name>    <value> ...

  5. 【学习笔记】深入理解js原型和闭包(18)——补充:上下文环境和作用域的关系

    本系列用了大量的篇幅讲解了上下文环境和作用域,有些人反映这两个是一回儿事.本文就用一个小例子来说明一下,作用域和上下文环境绝对不是一回事儿. 再说明之前,咱们先用简单的语言来概括一下这两个的区别. 0 ...

  6. ES6学习笔记(4)----正则的扩展

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 正则的扩展 ES6新增的正则表达式修饰符 u修饰符a.能够更准确地匹配unicode大于\uFF ...

  7. 【数据分析 R语言实战】学习笔记 第五章 数据的描述性分析(下)

    5.6 多组数据分析及R实现 5.6.1 多组数据的统计分析 > group=read.csv("C:/Program Files/RStudio/002582.csv") ...

  8. 云原生技术图谱 (CNCF Landscape)

    转自:https://raw.githubusercontent.com/cncf/landscape/master/landscape/CloudNativeLandscape_latest.jpg

  9. 浅析HashSet add() 方法存储自定义类型对象的过程

    一.自定义一个Student类 package date0504; public class Student { private String id; Student(String id){ this ...

  10. dns2tcp使用教程

    在2010年6月的更新(也是迄今为止最新的更新)后,其源代码支持编译为Windows平台的可执行程序.而且此工具使用C语言开发编写,不需要TUN/TAP,所以大大加强了它的可用性. 下载 当前最新的0 ...