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 ...
随机推荐
- Hadoop调度框架
大数据协作框架是一个桐城,就是Hadoop2生态系统中几个辅助的Hadoop2.x框架.主要如下: 1,数据转换工具Sqoop 2,文件搜集框架Flume 3,任务调度框架Oozie 4,大数 ...
- rhel7使用centos7yum组件
1)rpm -qa|grep yum --查看已安装的yum组件包 2)rpm -e 包名 --nodeps --卸载包 3)下载安装以下组件包: 使用rpm -ivh yum-* yum-3.4.3 ...
- Map集合的实现类
Map的继承关系: Map接口的常用实现类: 1.HashMap.Hashtable(t是小写) HashMap不是线程安全的,key.value的值都可以是null. Hashtable是线程安全的 ...
- Git之fatal: remote origin already exists
文件提交到远程分支,我们需要提前表明需要提交到哪个远程分支 比如:git remote add origin git@github.com:wqk66/test.git,表示他提交到远程仓库test ...
- 微信小程序 逻辑层
1. 注册程序小程序APP在小程序的根目录下有一个app.js文件.有App(Object),App() 函数用来注册一个小程序.接受一个 Object 参数,其内便是小程序的生命周期.App() 必 ...
- 新建cordova应用
使用命令行(本例命令行均使用as或webstrom的命令行),在任意目录输入以下命令新建cordova应用 cordova create capp1 com.cesc.ewater.capp1 其中c ...
- ag-grid-vue 本地删除,不重新刷新数据
// 这是本地删除,不重新刷新数据 that.gridListOptions.api.updateRowData({ remove: [that.submitTransmitData] });
- zabbix显示中文
- vue同胞组件通讯解决方案(以下为一种另外可用vuex解决)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- echarts简单用法快速上手
1.html结构 简单说就是一个标签一个图表:2.初始化:var myEcharts = echarts.init(document.getElementById("xxx")): ...