在环中(Going in Cycle!!, UVa 11090)
【题目描述】
给定一个 n 个点 m 条边的加权有向图,求平均权值最小的回路。
【输入格式】
输入第一行为数据组数 T 。每组数据第一行为图的点数 n 和边数 m (n ≤ 50)。以下 m 行每行3个整数 u, v, w, 表示有一条从 u 到 v 的有向边,权值为 w。输入没有自环。
【输出格式】
对于每组数据,输出平均最小值,并保留2位小数。如果误解,输出 "No cycle found."。
这道题吧,我觉得使用二分法求解不错。首先才一个值 mid,只需要判断是否存在平均值小于 mid 的回路。那么如何判断呢?假设存在一个包含 k 条边的回路,回路上各条边的权值为 w₁, w₂, w₃......(k 个),那么平均值小于 mid 意味着 w₁ + w₂ + w₃ +...... (k 个)< k * mid,即:
(w₁ - mid) + (w₂ - mid) + (w₃ - mid) + ......(k 组) < 0
这么看来,只要把每条边 (a, b) 的权 w(a, b) 变成 w(a, b) - mid,在判断图中是否有负全回路(负圈)即可。至于如何盘负圈,用 spfa 搜一遍图,若一个结点入队 n 次,那么就一定存在负圈。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = ;
const int maxx = 1e6 + ;
const double INF = 1e300; //double型一个很大的数
vector<int>v[maxn];
vector<double>c[maxn];
int cnt[maxn], vis[maxn]; //cnt[]入队次数
double dis[maxn];
int n, m;
void init()
{
for(int i = ; i < maxn; ++i)
{
v[i].clear(); c[i].clear();
}
}
bool spfa(double x)
{
for(int i = ; i < maxn; ++i) { cnt[i] = vis[i] = ; dis[i] = INF;}
queue<int>q;
for(int i = ; i <= n; ++i)
{
q.push(i); cnt[i]++; dis[i] = ;
} while(!q.empty())
{
int now = q.front(); q.pop();
vis[now] = ;
for(int i = ; i < v[now].size(); ++i)
{
if(dis[now] + c[now][i] - x < dis[v[now][i]]) //别忘减去 x!!
{
dis[v[now][i]] = dis[now] + c[now][i] - x;
if(!vis[v[now][i]])
{
q.push(v[now][i]); vis[v[now][i]] = ; cnt[v[now][i]]++; if(cnt[v[now][i]] > n) return true;
}
}
}
}
return false;
}
int main()
{
int T; scanf("%d", &T);
for(int kase = ; kase <= T; ++kase)
{
init();
printf("Case #%d: ", kase);
scanf("%d%d", &n, &m);
for(int i = ; i <= m; ++i)
{
int a, b, cost; scanf("%d%d%d", &a, &b, &cost);
v[a].push_back(b);
c[a].push_back(cost);
}
if(!spfa(maxx)) printf("No cycle found.\n"); //不存在负圈
else
{
double L = , R = maxx; //二分法求值
while(R - L > 1e-)
/*因为保留两位小数,所以只用让 L和 R相差小于0.01即可,这里选择0.001
注意:不能写 R == L,因为存在浮点误差,两个double型实数不能相等)*/
{
double mid = (L + R) / ;
if(spfa(mid)) R = mid;
else L = mid;
}
printf("%.2lf\n", L);
}
}
}
在环中(Going in Cycle!!, UVa 11090)的更多相关文章
- Going in Cycle!! UVA - 11090(二分+判断环路 )
题意: 给定一个n个点m条边的加权有向图,求平均权值最小的回路 解析: 首先肯定是想到找出环路 然后..呵..呵..呵呵... 显然不现实!! 二分大法好 ....去猜结果 然后带入验证 ...真是 ...
- 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)
layout: post title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环) author: "luowentaoaa" catalog: ...
- UVA 11090 - Going in Cycle!!(Bellman-Ford)
UVA 11090 - Going in Cycle!! option=com_onlinejudge&Itemid=8&page=show_problem&category= ...
- UVA - 11090 - Going in Cycle!!(二分+差分约束系统)
Problem UVA - 11090 - Going in Cycle!! Time Limit: 3000 mSec Problem Description You are given a we ...
- UVA 11090 Going in Cycle!! SPFA判断负环+二分
原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVA 11090 - Going in Cycle!! SPFA
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- Uva 11090 在环中
题目链接:http://vjudge.net/contest/143318#problem/A 题意: 求平均权值最小的回路. 分析: 平均权值不可能超过最大边,二分查,然后,由于是平均权值,就可以转 ...
- UVa 11090 Going in Cycle!!【Bellman_Ford】
题意:给出n个点m条边的加权有向图,求平均值最小的回路 自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对 后来看书= =好巧妙的办法, 使用 ...
- UVA 11090 Going in Cycle!!(二分答案+判负环)
在加权有向图中求平均权值最小的回路. 一上手没有思路,看到“回路”,第一想法就是找连通分量,可又是加权图,没什么好思路,那就转换题意:由求回路权值->判负环,求最小值->常用二分答案. 二 ...
随机推荐
- [BZOJ 4671]异或图
Description 题库链接 给定 \(s\) 个结点数相同且为 \(n\) 的图 \(G_1\sim G_s\) ,设 \(S = \{G_1, G_2,\cdots , G_s\}\) ,问 ...
- ES6+ 开发 React 组件
在这里简要的说一下这些语言新特性对 React 应用的开发有什么影响,这些 ES6+ 特性使得 React 开发更简单更有趣. 类 迄今为止,最能体现我们使用 ES6+ 来编写 React 组件的就是 ...
- (转)分享一个技巧,利用批处理调用ruby脚本(可能你为路径苦恼)
#关闭命令显示 @echo off #提示信息 echo Now,listing the controller,please not shutdown the DOS File! #切换到当前路径,. ...
- 《SQL Server从入门到精通》
书名 <SQL Server从入门到精通> 图片 时间 2017-6月 学习 书还可以看完不痛不痒 光盘里面是c的视频有趣这是要我学c的节奏啊,可以写一些基础sql语句也是一门语言叫T-s ...
- jdk1.7安装,cmd下 java -version出现错误:“could not open `D:\Java\jre7\lib\amd64\jvm.cfg”
cmd 下java -version出现错误:“could not open `D:\Java\jre7\lib\amd64\jvm.cfg”,出现这种错误可能是由于先前有安装老版本jdk,之后将新版 ...
- [PHP] 数据结构-线性表的顺序存储结构PHP实现
1.PHP中的数组实际上是有序映射,可以当成数组,列表,散列表,字典,集合,栈,队列,不是固定的长度2.数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了3.想要函数的一个参数 ...
- 01-初始Java
1. 你学习编程的目的是什么?学习编程最快的办法是什么? 答:我喜欢计算机,想更多的了解计算机的原理:我认为学习最快的办法就是尝试,只有不断地在计算机上尝试编程,遇到错误, 解决错误,才能更快的学会编 ...
- Matlab .asv是什么文件
有时在存放m文件的文件夹中会出现*.asv asv 就是auto save的意思,*.asv文件的内容和相应的*.m文件内容一样,用记事本和matlab都能打开它.它可以作为*.m文件的"备 ...
- Angular6封装LED时钟数字组件
一.运行截图 截图1: 截图2: 二.代码 html代码: <div class="time" > <ng-container #container> &l ...
- JS的防抖,节流,柯里化和反柯里化
今天我们来搞一搞节流,防抖,柯里化和反柯里化吧,是不是一看这词就觉得哎哟wc,有点高大上啊.事实上,我们可以在不经意间用过他们但是你却不知道他们叫什么,没关系,相信看了今天的文章你会有一些收获的 节流 ...