题目链接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. Spark SQL catalyst概述和SQL Parser的具体实现

    之前已经对spark core做了较为深入的解读,在如今SQL大行其道的背景下,spark中的SQL不仅在离线batch处理中使用广泛,structured streamming的实现也严重依赖spa ...

  2. 【译】建立属于你的个人高效系统——效率专家 Mike Vardy 教你如何设置一个简单的个人高效系统

    原文:http://mux.baidu.com/?p=5300 百度MUX 已经有太多的高效系统供人使用,而对于那些刚刚开始,想寻求更好方法完成他们任务,项目,目标的人来说,要做一个高效系统却是相当艰 ...

  3. 启动hadoop时报root@localhost's password: localhost: Permission denied, please try again.错误。

    背景:在装完hadoop及jdk之后,在执行start-all.sh的时候出现root@localhost's password:localhost:permission denied,please ...

  4. Spring Boot 注册 Servlet 的三种方法,真是太有用了!

    本文栈长教你如何在 Spring Boot 注册 Servlet.Filter.Listener. 你所需具备的基础 什么是 Spring Boot? Spring Boot 核心配置文件详解 Spr ...

  5. shutil模块详解2

    1.shutil.make_archive() 实际上是调用了两个模块来实现压缩打包的功能. zipfile和tarfile两个模块,shutil的两个封装的模块. zip是压缩文件,文件内存会变小, ...

  6. poj2441 Arrange the Bulls

    思路: 状态压缩dp.需要一点优化,否则容易超时. 实现: #include <cstdio> #include <vector> #include <cstring&g ...

  7. DAX:New and returning customers

    The New and Returning Customers pattern dynamically calculates the number of customers with certain ...

  8. 基于SAE的Python+Django部署

    本文主要参考:http://www.cnblogs.com/qtsharp/archive/2012/01/12/2320774.html,另外包括自己的实际操作. 一.申请SAE帐号以及创建应用ya ...

  9. (转)使用Spring的注解方式实现AOP入门

    http://blog.csdn.net/yerenyuan_pku/article/details/52865330 首先在Eclipse中新建一个普通的Java Project,名称为spring ...

  10. laravel homestead comoser install 报错

    项目部署的时候composer install报错 说那个依赖包没有安装成功需要回滚删除但是删除不了 解决: 要配置共享文件 注:使用 NFS 的话,需要安装 vagrant-winnfsd 插件.该 ...