题意描述

Sightseeing Cows G

给定一张有向图,图中每个点都有点权 \(a_i\),每条边都有边权 \(e_i\)。

求图中一个环,使 “环上个点权之和” 除以 “环上各边权之和” 最大。输出最大值。

解释一下,原题目中并没有点明这是一个环,但是从:

奶牛们不会愿意把同一个建筑物参观两遍。

可以看出,不管怎么走,走环一定是最优的,因为重复走相当于无故增加分母。

算法分析

据说这是一道 0/1 分数规划的题目,但是其实可以用更加通俗易懂的方法来解释。

假设用 \(v_i,e_i(1\leq i\leq k)\) 分别表示环上的点权和边权。

那么显然题目就是要找到最大的 \(\frac{\sum^{k}_{i=1} v_i}{\sum^{k}_{i=1} e_i}\)。

利用二分答案,当 \(\sum^k_{i=1} (mid\times e_i-v_i)<0\) 时:\(mid<\frac{\sum^{k}_{i=1} v_i}{\sum^{k}_{i=1} e_i}\),令 \(l=mid\)。

反之,当 \(\sum^k_{i=1} (mid\times e_i-v_i)\geq 0\):\(mid\geq \frac{\sum^{k}_{i=1} v_i}{\sum^{k}_{i=1} e_i}\),令 \(r=mid\)。

那么就将 \(e(x,y)\) 转化为 \(mid\times e_i-a[x]\),利用 SPFA 判断是否有负环即可。

代码实现

应为题目不保证图的连通性,所以 SPFA 开始的时候将所有点都入队。

利用二分答案将最优解变为判定即可。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define N 10010
#define M 50010
using namespace std; int n,m,a[N],head[N],cnt=0,sum[N];
bool vis[N];
double dis[N];
struct Edge{
int nxt,to,val;
}ed[N<<1]; int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
} void add(int u,int v,int w){
ed[++cnt].nxt=head[u];
ed[cnt].to=v,ed[cnt].val=w;
head[u]=cnt;
return;
} bool chck(double mid){
queue<int>q;
for(int i=1;i<=n;i++){
q.push(i);
dis[i]=0,vis[i]=true,sum[i]=1;
}
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=false;
if(++sum[u]>=n) return true;
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to;
double w=ed[i].val;
if(dis[v]>dis[u]+(double)(mid*w-(double)a[u])){//注意一下 double 与 int
dis[v]=dis[u]+(double)(mid*w-(double)a[u]);
if(!vis[v]) q.push(v),vis[v]=true;
}
}
}
return false;
} int main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(u,v,w);
}
double l=0.0,r=1000010.0,mid,eps=1e-5;
while(r-l>eps){
mid=(l+r)/2;
if(chck(mid)) l=mid;
else r=mid;
}
printf("%.2lf",l);
return 0;
}

完结撒花

P2868 [USACO07DEC]Sightseeing Cows G的更多相关文章

  1. [USACO07DEC]Sightseeing Cows(负环,0/1分数规划)

    [USACO07DEC]Sightseeing Cows Description Farmer John has decided to reward his cows for their hard w ...

  2. 【洛谷P2868】Sightseeing Cows

    题目大意:给定一个 N 个点,M 条边的有向图,点有点权,边有边权,求该有向图中的一个环,使得环上点权和与环上边权和之比最大. 题解:0/1 分数规划思想,每次二分一个 mid,在新图上跑 spfa, ...

  3. [USACO07DEC]Sightseeing Cows

    嘟嘟嘟 这题好像属于01分数规划问题,叫什么最优比率生成环. 题目概括一下,就是求一个环,满足∑v[i] / ∑c[i]最大. 我们可以堆上面的式子变个型:令 x = ∑v[i] / ∑c[i],则x ...

  4. P2868 [USACO07DEC]观光奶牛Sightseeing Cows

    P2868 [USACO07DEC]观光奶牛Sightseeing Cows [](https://www.cnblogs.com/images/cnblogs_com/Tony-Double-Sky ...

  5. 洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows

    P2868 [USACO07DEC]观光奶牛Sightseeing Cows 题目描述 Farmer John has decided to reward his cows for their har ...

  6. 【POJ3621】Sightseeing Cows

    Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8331   Accepted: 2791 ...

  7. POJ 3621 Sightseeing Cows(最优比例环+SPFA检测)

    Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10306   Accepted: 3519 ...

  8. Sightseeing Cows(最优比率环)

    Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8915   Accepted: 3000 ...

  9. 【POJ3621】Sightseeing Cows 分数规划

    [POJ3621]Sightseeing Cows 题意:在给定的一个图上寻找一个环路,使得总欢乐值(经过的点权值之和)/ 总时间(经过的边权值之和)最大. 题解:显然是分数规划,二分答案ans,将每 ...

随机推荐

  1. PageObject课程培训记录

    前言 昨晚的培训课程讲了PO设计模式,对于PO模式我们需要去了解关于为什么要使用PO,而不使用PO是什么情况?什么是PO模式?PO怎么去使用? 第一,为什么要使用PO,而不使用PO是什么情况? 我们先 ...

  2. Python练习题 008:打印101-200之间的所有素数

    [Python练习题 008]判断101-200之间有多少个素数,并输出所有素数. ---------------------------------------------------------- ...

  3. KEIL查看ARM-Cortex M架构soc的内核寄存器之 MSP

       参考下图stm32l475的参考手册: MSP指向地址基地址为0x20000000的内存处.参考STM32L475的memory map可知MSP指向的是SRAM的一块地址.并且由上面的编译信息 ...

  4. Code Test(2)

    1110test T1:Inversion逆序数对1(inversion.cpp/in/out 1s 256M)给定N的值,要求找出一个N的全排列,这个全排列中,逆序数有M对.这样的结果会存在多个解, ...

  5. CentOS 7安装docker和常用指令

    1.安装 yum -y install docker 2.启动 systemctl start docker // 启动 docker -v //查看版本号 systemctl stop docker ...

  6. for循环迭代可迭代对象

    模仿for循环迭代可迭代对象,# for i in Iterable:# iterable >>> 迭代器.iterator# 可迭代对象 iterable# 迭代器.iterato ...

  7. 网易新闻精彩评论集合(慢慢收集ing)

    一.刚才在停车场看一男的开个Q7,怎么也停不进去.我迅速把车停好要过去帮忙,他死活不同意.我说,你刚也看见了我的停车技术了,肯定不能给你刮了.他干脆把窗户摇上了.如今的社会啊,人与人的互信程度为什么就 ...

  8. 租房数据分析,knn算法使用

    import numpy as np import pandas as pd import matplotlib.pyplot as plt data = pd.read_excel('jiemo.x ...

  9. C#使用RabbitMq队列(Sample,Work,Fanout,Direct等模式的简单使用)

    1:RabbitMQ是个啥?(专业术语参考自网络) RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件). RabbitMQ服务器是用Erlang语言编写的, ...

  10. 【源码项目+解析】C语言/C++开发,打造一个小项目扫雷小游戏!

    一直说写个几百行的小项目,于是我写了一个控制台的扫雷,没有想到精简完了代码才200行左右,不过考虑到这是我精简过后的,浓缩才是精华嘛,我就发出来大家一起学习啦,看到程序跑起来能玩,感觉还是蛮有成就感的 ...