题目链接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. Centos系统安装 phpredis 扩展

    Git地址:https://github.com/nicolasff/phpredis 一.安装: phpize ./configure make && make install 其中 ...

  2. 11.1Java-接口

    一.接口 interface定义:固定格式 public abstract 返回值类型 方法名字(参数列表);代码: public interface AMyInterface { public ab ...

  3. 用私有构造器或者枚举类型强化Singleton

    参考Effective Java第三版 Joshua J. Bloch 参与编写JDK的大佬,上次看Collections的源码时看见了他的名字,然后翻了翻书,竟然就是他写的! 1.常见的一种: pu ...

  4. 【转】Java泛型方法

    1. 定义泛型方法 (1) 如果你定义了一个泛型(类.接口),那么Java规定,你不能在所有的静态方法.静态初块等所有静态内容中使用泛型的类型参数.例如: public class A<T> ...

  5. grunt配置详情

    这个grunt配置 是我的一个程序员朋友从网上无意间看到的,然后他亲测了下,恩,是可以的.不过我到目前还未测试过是否可以. 一.安装node, 首先确保电脑已有node的环境.然后 运行  npm i ...

  6. WARN警告:Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended

    使用Apache HttpClient发送请求,有大量WARN警告:Going to buffer response body of large or unknown size. Using getR ...

  7. std::map插入已存在的key时,key对应的内容不会被更新

    std::map插入已存在的key时,key对应的内容不会被更新,如果不知道这一点,可能会造成运行结果与预期的不一致 “Because element keys in a map are unique ...

  8. JS通过使用PDFJS实现基于文件流的预览功能

    需求: 使用JS实现PDF文件预览功能 备选方案: 使用ViewerJS,官网  http://viewerjs.org/ 使用PDFJS,官网  https://mozilla.github.io/ ...

  9. springcloud 之 bus 消息总线

    在分布式系统中,我们通常使用轻量级消息代理(rabbitmq.kafuka)建立一个公共的主题,让所有的微服务都链接进来,并且监听消费这个主题的内容,我们就称这个主题是 消息总线. (可以用作配置文件 ...

  10. oracle的系统表

    -- DBA/ALL/USER/V_$/GV_$/SESSION/INDEX开头的绝大部分都是视图-- DBA_TABLES意为DBA拥有的或可以访问的所有的关系表.-- ALL_TABLES意为某一 ...