HNOI2019 最小圈
2024-09-08 16:55:08
\(\text{Problem}\)
对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过 \(k\) 个节点,那么一个圈的平均值为圈上 \(k\) 条边权的和除以 \(k\),现要求其中的最小值
\(\text{Solution}\)
经典的分数规划题
很容易想到二分答案
那么我们要找到一个 \(T\) 个点的环满足
\(\frac{\sum_{i=1}^T e_i}{T} \le mid\)
把 \(T\) 乘过来,移项得
\(\sum_{i=1}^T [e_i-mid] \le 0\)
于是 \(dfs\) 暴力寻找这样的环
这种 \(dfs\) 相当于 \(dfs\) 版本的 \(spfa\),不会超时
注意这份代码是 \(\text{JZOJ 5173}\) 的
题目是一样的,输出的区别罢了
\(\text{Code}\)
#include<cstdio>
using namespace std;
const int N = 1005, M = 10005;
int n, m, vis[N], h[N];
double dis[N], mid;
struct edge{
int to, nxt, w;
}e[M];
inline void add(int u, int v, int w)
{
static int tot = 0;
e[++tot] = edge{v, h[u], w}, h[u] = tot;
}
int dfs(int x)
{
vis[x] = 1;
for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
double w = 1.0 * e[i].w - mid;
if (dis[x] + w <= dis[v])
{
dis[v] = dis[x] + w;
if (vis[v] || dfs(v)) return 1;
}
}
vis[x] = 0;
return 0;
}
inline int check()
{
for(register int i = 1; i <= n; i++) vis[i] = 0, dis[i] = 0;
for(register int i = 1; i <= n; i++) if (dfs(i)) return 1;
return 0;
}
int main()
{
scanf("%d%d", &n, &m);
for(register int i = 1, u, v, w; i <= m; i++)
scanf("%d%d%d", &u, &v, &w), add(u, v, w);
double l = 0, r = 1e7, ans, bz = 0;
while (r - l > 1e-12)
{
mid = (l + r) / 2;
if (check()) r = mid, ans = mid, bz = 1;
else l = mid;
}
if (bz) printf("%.2lf", l);
else printf("PaPaFish is laying egg!");
}
最新文章
- python基础一
- Scala的模式匹配
- CSS实现水平垂直同时居中的5种思路
- iOS开源项目MobileProject功能点介绍
- DataGridview焦点不移开不保存数据问题
- 服务器中判断客户端socket断开连接的方法
- yii中阻止 SHOW CREATE TABLE and SHOW COLUMNS 每次执行
- js 如何把JSON格式的字符串转换为JSON对象
- 斐波那契数列(fabnacci)java实现
- DLP底座(威创定制)
- Matlab命令行编译运行HelloWorld
- JS画几何图形之六【过直线外一点作垂线】
- 一 Unicode和UTF-8的异同
- 使用cobbler工具实现centos 6,7系统的自动化安装
- 你可能不知道的 Mac 技巧 - 文本操作
- [译]在Linux上的提高MySQL/MariaDB安全性的12条建议
- 用Rider写一个由Autofac管理资源的WebAPI应用程序
- BM25 调参调研
- 在QT中用git做版本管理时遇到的一些问题
- Hyperledger Fabric chaincode 开发(疑难解答)