当前位置: 首页 > news >正文

BZOJ1486 最小圈 [分数规划+负权环]

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\)中的一个圈当且仅当
\((ci,ci+1)(1≤i<k)\)\((ck,c1)\)都在\(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\)

思路

看到题目中的“平均值的最小值”,便想到可以分数规划,这道题运用的是0-1分数规划的思想。

0-1分数规划的一般形式是这样一个式子:
\(r=(∑(c_i*x_i))/(∑(d_i*x_i))\) 在其中 \(x_i∈\){0,1}

我们一般求的便是r的最值。有一种基础的方法是二分r的值:
将原式变形,\(∑(c_i*x_i))-(∑(d_i*x_i)*r=0\)
\(f(r)=∑(c_i*x_i))-(∑(d_i*x_i)*r\)

不难看出\(f(r)\)是单调递减的函数,我们可以通过\(f(r)\)与0的关系来二分出r的最值:
\(f(r)>0\)时 表明这时r可以取更大
\(f(r)=0\)时 表明这时r即为符合要求的最值
\(f(r)<0\)时 表明这时r可以取更小

我们便在本题中运用这个思想。在本题中,公式中的r即为最小的平均值,c即为边权,d为1 (∑\(d_i*x_i\)即为边的个数),x表示这条边是否在圈中,f(r)转换后可以看作是边权减去r后最小圈的权值之和。

当f(r)<0时,这个圈就是负权环,于是我们便可以根据是否存在负权环来二分出r的值。
我判断负权环的方法是使用dfs-spfa,详细内容可以看代码(顺便给出模板题链接洛谷P3385)。

代码

需要注意的细节:

  1. 注意二分的精度
  2. 判负环注意方法,不然容易T
#include <bits/stdc++.h>
#define exp 1e-9  //二分的精度
#define inf 1e9
#define MAXN 10005
using namespace std;
int n,m,a[MAXN],b[MAXN];
int cnt,head[MAXN],vis[MAXN],flag;
double dis[MAXN],c[MAXN]; //一定要用double存
struct Edge{int to,next; double w;} edge[MAXN];

void addedge(int x, int y, double w)
{ //前向星存图
    edge[++cnt].next=head[x];
    edge[cnt].to=y;
    edge[cnt].w=w;
    head[x]=cnt;
}

void spfa(int x)
{  //dfs_spfa判负环
    vis[x]=true;
    for(int i=head[x]; i; i=edge[i].next)
    {
        int to=edge[i].to;
        if(dis[x]+edge[i].w<dis[to])
        {
            dis[to]=dis[x]+edge[i].w;
            if(vis[to]) {flag=true; return;}
            else spfa(to);
        }
    }
    vis[x]=false;
}

bool check(double x)
{
    cnt=flag=0;
    memset(head, 0, sizeof(head));
    memset(dis, 127/3, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    for(int i=1; i<=m; i++) addedge(a[i], b[i], c[i]-x); //重新赋权值
    for(int i=1; i<=n; i++)
    {
        spfa(i); //判负环
        if(flag) return 1;  
    }
    return 0;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++) scanf("%d%d%lf",&a[i],&b[i],&c[i]);
    double l=-inf,r=inf;
    while(l+exp<r) //分数规划
    {
        double mid=(l+r)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%.8lf",l);
    return 0;
} 

转载于:https://www.cnblogs.com/CrazyDave/p/8465383.html

相关文章:

  • 医疗成像领域引进人工智能: AI 帮助医生进行成像分析
  • linux命令总结basename
  • 遍历字典 NSDictionary
  • 2012金华邀请赛解题报告
  • Java9 新特性 详解
  • 设置Google浏览器不缓存JS
  • IntelliJ Idea 常用快捷键列表
  • SpringCloud教程 | 第三篇: 服务消费者(Feign)
  • 前端远程调试
  • 与Brian Goetz聊Java的数据类
  • Git 系列(一):什么是 Git
  • 第十一章 LAMP架构
  • 《Arduino实战》——第1章 你好Arduino 1.1 Arduino简史
  • C++程序设计:原理与实践(进阶篇)17.7 使用Shape类
  • 微信小程序计算器后后续
  • [iOS]Core Data浅析一 -- 启用Core Data
  • [Vue CLI 3] 配置解析之 css.extract
  • 2018一半小结一波
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • exports和module.exports
  • mysql 5.6 原生Online DDL解析
  • orm2 中文文档 3.1 模型属性
  • PAT A1050
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Python学习之路13-记分
  • QQ浏览器x5内核的兼容性问题
  • React+TypeScript入门
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • XML已死 ?
  • 大型网站性能监测、分析与优化常见问题QA
  • 开源SQL-on-Hadoop系统一览
  • 每天一个设计模式之命令模式
  • 我是如何设计 Upload 上传组件的
  • UI设计初学者应该如何入门?
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • #define,static,const,三种常量的区别
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (14)Hive调优——合并小文件
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (js)循环条件满足时终止循环
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (办公)springboot配置aop处理请求.
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (转) Android中ViewStub组件使用
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET MVC 验证码
  • .net 程序发生了一个不可捕获的异常
  • .NET导入Excel数据
  • .NET框架设计—常被忽视的C#设计技巧
  • .net流程开发平台的一些难点(1)
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @ConditionalOnProperty注解使用说明
  • [AAuto]给百宝箱增加娱乐功能
  • [Angularjs]asp.net mvc+angularjs+web api单页应用