UVA 11090 判负圈问题
题目链接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 判负圈问题的更多相关文章
- LightOJ-1074(SPFA判负圈+Bellman-Ford算法)
Extended Traffic LightOJ-1074 这题因为涉及到减法和三次方,所以可能会出现负圈. 这里使用的算法叫做SPFA算法,这个可以用来判负圈和求解最短路.Bellman-Ford算 ...
- BZOJ 1486: [HNOI2009]最小圈( 二分答案 + dfs判负圈 )
二分答案m, 然后全部边权减掉m, 假如存在负圈, 那么说明有平均值更小的圈存在. 负圈用dfs判断. ------------------------------------------------ ...
- POJ-3259(最短路+Bellman-Ford算法判负圈)
Wormholes POJ-3259 这题是最短路问题中判断是否存在负圈的模板题. 判断负圈的一个关键就是理解:如果在图中不存在从s可达的负圈,最短路径不会经过一个顶点两次.while循环最多执行v- ...
- [poj3259]Wormholes(spfa判负环)
题意:有向图判负环. 解题关键:spfa算法+hash判负圈. spfa判断负环:若一个点入队次数大于节点数,则存在负环. 两点间如果有最短路,那么每个结点最多经过一次,这条路不超过$n-1$条边. ...
- 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)
layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: ...
- UVA 11090 Going in Cycle!!(二分答案+判负环)
在加权有向图中求平均权值最小的回路. 一上手没有思路,看到“回路”,第一想法就是找连通分量,可又是加权图,没什么好思路,那就转换题意:由求回路权值->判负环,求最小值->常用二分答案. 二 ...
- UVA 11090 Going in Cycle!!(Bellman-Ford推断负圈)
题意:给定一个n个点m条边的加权有向图,求平均权值最小的回路. 思路:使用二分法求解.对于每个枚举值mid,推断每条边权值减去mid后有无负圈就可以. #include<cstdio> # ...
- 【dfs判负环】BZOJ1489: [HNOI2009]最小圈
Description 找出一个平均边权最小的圈. Solution 经典问题,二分答案判断有无负环. 但数据范围大,普通spfa会超时,于是用dfs判负环(快多了). 思路是dis设为0,枚举每个点 ...
- [HNOI2009]最小圈 分数规划 spfa判负环
[HNOI2009]最小圈 分数规划 spfa判负环 题面 思路难,代码简单. 题目求圈上最小平均值,问题可看为一个0/1规划问题,每个边有\(a[i],b[i]\)两个属性,\(a[i]=w(u,v ...
随机推荐
- 【学习笔记】block、inline(替换元素、不可替换元素)、inline-block的理解
本文转载 总体概念 block和inline这两个概念是简略的说法,完整确切的说应该是 block-level elements (块级元素) 和 inline elements (内联元素).blo ...
- 【java基础】Java锁机制
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁(广义) 互斥锁/读写锁(独享锁/共享锁的实现) 乐观锁 ...
- Failed to obtain lock on file /usr/local/nagios/var/ndo2db.lock: Permission denied : Permission denied
Failed to obtain lock on file /usr/local/nagios/var/ndo2db.lock: Permission denied : Permission den ...
- Entity Framework + MySQL 使用笔记
添加: using (var edm = new NorthwindEntities()) { Customers c = ", Region = "天府广场", Con ...
- java中异常处理finally和return语句的执行顺序
finally代码块的语句在return之前一定会得到执行 如果try块中有return语句,finally代码块没有return语句,那么try块中的return语句在返回之前会先将要返回的值保存, ...
- Angularjs 实现 $(document).ready()的两种方法
1.在controller里面利用$on或者$watch bookControllers.controller('bookctrl_test', ['$scope', '$routeParams', ...
- Database coalesce
coalesce 语法 注意:连接操作符“||”是一个值得注意的例外. 例如,空值加任何值都是空值,空值 乘任何值也都是空值,依此类推. 参数 expression 任何类型的表达式. n 表示可以指 ...
- slides 在线ppt && React && Angular
现在主流前端框架 有3个 Vue React Angular 如果有时间就都学习,理解一下他们的差异性~ 在线ppt的一个网站 这个是npm讲解的,不错 https://slides.com/seld ...
- centos下安装nodejs的三种种方式
方法一:源码包安装 官网下载 centos下载最新版10.9 https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.xz mkdir / ...
- vue 数据没有驱动视图?
Part.1 问题 数据改变,视图却没有根据数据而改变. 原因在于,数据并不在 vue 监听范围之内,vue 只对事先在 data 中声明的变量丶对象等类型数据进行监听 Part.2 例子 < ...