Description

考虑带权的有向图$G=(V,E)$以及$w:E\rightarrow R$,每条边$e=(i,j)(i\neq j,i\in V,j\in V)$的权值定义为$w_{i,j}$,令$n=|V|$。$c=(c_1,c_2,\cdots,c_k)(c_i\in V)$是$G$中的一个圈当且仅当$(c_i,c_{i+1})(1\le i<k)$和$(c_k,c_1)$都在$E$中,这时称$k$为圈$c$的长度同时令$c_{k+1}=c_1$,并定义圈$c=(c_1,c_2,\cdots,c_k)$的平均值为$\mu(c)=\sum\limits_{i=1}^{k} w_{c_i,c_{i+1}}/k$,即$c$上所有边的权值的平均值。令$\mu'(c)=Min(\mu(c))$为$G$中所有圈$c$的平均值的最小值。现在的目标是:在给定了一个图$G=(V,E)$以及$w:E\rightarrow R$之后,请求出$G$中所有圈$c$的平均值的最小值$\mu'(c)=Min(\mu(c))$

Input

第一行2个正整数,分别为$n$和$m$,并用一个空格隔开,只用$n=|V|,m=|E|$分别表示图中有$n$个点$m$条边。 接下来m行,每行3个数$i,j,w_{i,j}$,表示有一条边$(i,j)$且该边的权值为$w_{i,j}$。输入数据保证图$G=(V,E)$连通,存在圈且有一个点能到达其他所有点。

Output

请输出一个实数$\mu'(c)=Min(\mu(c))$,要求输出到小数点后8位。

Sample Input

4 5
1 2 5
2 3 5
3 1 5
2 4 3
4 1 3

Sample Output

3.66666667

HINT

对于100%的数据,$n\le 3000,m\le 10000,|w_{i,j}| \le 10^7$

题解

最小化平均值($01$分数规划)。

使用二分求解。对于一个猜测的$mid$,只需判断是否存在平均值小于$mid$的回路。

如何判断?

假设存在一个包含$k$条边的回路,回路上各边权值为$w_1$ ,$w_2$ ,$...$,$w_k$ ,那么平均值小于$midv$意味着:

$$w_1 +w_2 +...+w_k <k×mid$$

即:

$$(w_1 -mid)+(w_2 -mid)+...+(w_k -mid)<0$$

换句话说,只要把边$(a,b)$的权$w(a,b)$改成$w(a,b)-mid$,再判断新图中是否有负环即可。

存在负环,那么之前的不等式满足,即存在着更小的平均值,$r=mid$;不存在,$l=mid$。

 //It is made by Awson on 2017.10.9
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define sqr(x) ((x)*(x))
using namespace std;
const double eps = 1e-;
const int N = ;
const int M = ; int n, m, u, v, c;
bool vis[N+];
double dist[N+];
struct tt {
int to, next;
double cost;
}edge[M+];
int path[N+], top; void add(int u, int v, double c) {
edge[++top].to = v;
edge[top].next = path[u];
edge[top].cost = c;
path[u] = top;
}
bool dfs(int u, double dec) {
vis[u] = ;
for (int i = path[u]; i; i = edge[i].next)
if (dist[edge[i].to] > dist[u]+edge[i].cost-dec) {
if (vis[edge[i].to]) {vis[u] = ; return true;}
dist[edge[i].to] = dist[u]+(double)edge[i].cost-dec;
if (dfs(edge[i].to, dec)) {vis[u] = ; return true;}
}
vis[u] = ;
return false;
}
bool judge(double dec) {
memset(dist, , sizeof(dist));
for (int i = ; i <= n; i++)
if (dfs(i, dec)) return true;
return false;
}
void work() {
scanf("%d%d", &n, &m);
double L = , R = ;
for (int i = ; i <= m; i++) {
scanf("%d%d%d", &u, &v, &c);
add(u, v, c);
R = max(R, (double)c);
}
while (R-L >= eps) {
double mid = (L+R)/.;
if (judge(mid)) R = mid;
else L =mid;
}
printf("%.8lf\n", (L+R)/.);
}
int main() {
work();
return ;
}

[HNOI 2009]最小圈的更多相关文章

  1. bzoj 1486: [HNOI2009]最小圈 dfs求负环

    1486: [HNOI2009]最小圈 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1022  Solved: 487[Submit][Status] ...

  2. BZOJ 1486: [HNOI2009]最小圈( 二分答案 + dfs判负圈 )

    二分答案m, 然后全部边权减掉m, 假如存在负圈, 那么说明有平均值更小的圈存在. 负圈用dfs判断. ------------------------------------------------ ...

  3. [HNOI2009]最小圈

    题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除以k,现要求其中的最小值 输入输出格式 输入格式: 第一行2个正整数,分别为 ...

  4. BZOJ_1486_[HNOI2009]最小圈_01分数规划

    BZOJ_1486_[HNOI2009]最小圈_01分数规划 Description Input Output Sample Input 4 5 1 2 5 2 3 5 3 1 5 2 4 3 4 1 ...

  5. [HNOI2009]最小圈 (二分答案+负环)

    题面:[HNOI2009]最小圈 题目描述: 考虑带权的有向图\(G=(V,E)\)以及\(w:E\rightarrow R\),每条边\(e=(i,j)(i\neq j,i\in V,j\in V) ...

  6. 【题解】 [HNOI2009] 最小圈 (01分数规划,二分答案,负环)

    题目背景 如果你能提供题面或者题意简述,请直接在讨论区发帖,感谢你的贡献. 题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除 ...

  7. bzoj千题计划227:bzoj1486: [HNOI2009]最小圈

    http://www.lydsy.com/JudgeOnline/problem.php?id=1486 二分答案 dfs版spfa判负环 #include<queue> #include ...

  8. 洛谷4951 地震 bzoj1816扑克牌 洛谷3199最小圈 / 01分数规划

    洛谷4951 地震 #include<iostream> #include<cstdio> #include<algorithm> #define go(i,a,b ...

  9. 【BZOJ1486】[HNOI2009]最小圈 分数规划

    [BZOJ1486][HNOI2009]最小圈 Description Input Output Sample Input 4 5 1 2 5 2 3 5 3 1 5 2 4 3 4 1 3 Samp ...

随机推荐

  1. Beta Scrum Day 7

    听说

  2. 利用PCA降维

    参考:<机器学习实战>- Machine Learning in Action 一. 基本思想  PCA(Principal Component Analysis),主成分分析.是目前应用 ...

  3. OpenCASCADE Trihedron Law

    OpenCASCADE Trihedron Law eryar@163.com Abstract. In differential geometry the Frenet-Serret formula ...

  4. MySQL默认储存引擎修改

    1.输入以下SQL语句查看当前储存引擎支持: SHOW ENGINES; 如图所示本机默认引擎为MyISAM: 2.若要修改引擎执行: ALTER TABLE 表名 ENGINE = 储存引擎名: 3 ...

  5. 剑指offer-删除链表中重复的节点

    题目描述   在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处 ...

  6. c# 字符串的内存分配和驻留池( 转 )

    刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例.如下: string s1 = "he ...

  7. 算法题丨3Sum Closest

    描述 Given an array S of n integers, find three integers in S such that the sum is closest to a given ...

  8. SpringCloud的应用发布(四)顺序启动各个应用

    一.部署应用 二.启动应用(注意顺序) 三.观察效果 1.查看进程和日志 ps -ef | grep java tail -f AppYml.txt 2.验证功能

  9. GIT入门笔记(17)- 创建分支dev_lsq, 提交到代码

    git服务器上默认的已经有主干和test分支. 开发人员提交代码流程如下: 1.用switch to->new branch创建dev1分支 2.push branch提交到dev1分支 3.在 ...

  10. python入门(7)Python程序的风格

    python入门(7)Python程序的风格 Python采用缩进方式,写出来的代码就像下面的样子: # print absolute value of an integer: a = 100 if ...