题意描述

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. 剑指offer-二叉树

    1. 平衡二叉树 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 解: 要么是一颗空树,要么左右子树都是平衡二叉树且左右子树深度之差不超过1 1 # class TreeNode: 2 # def _ ...

  2. golang go语言 实现链表

    package main import ( "errors" "fmt" "strconv" ) type List struct { Le ...

  3. chrome浏览器的两个坑,以及其他

    chrome打开本地网页时,不能保存cookiechrome拒绝使用ajax访问本地文件(火狐可以) ipinfo.io/ip 获得公网iphttps://v1.hitokoto.cn/ 获得一句动漫 ...

  4. 014 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 08 “字符型”字面值

    014 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 08 "字符型"字面值 字符型 字面值如何表示? 两个关键:单引号(必须是英文单引号). ...

  5. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

  6. C++ 双冒号开头的语法是什么

    z转载:https://blog.csdn.net/LHHopencv/article/details/78353380 命名空间限定.std::string 表示std命名空间下的 string类. ...

  7. Linux中的硬链接和软连接

    1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节点 ...

  8. JDK 中的栈竟然是这样实现的?

    前面的文章<动图演示:手撸堆栈的两种实现方法!>我们用数组和链表来实现了自定义的栈结构,那在 JDK 中官方是如何实现栈的呢?接下来我们一起来看. 这正式开始之前,先给大家再解释一下「堆栈 ...

  9. Java安全之Commons Collections1分析(二)

    Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...

  10. CSS字体属性与文本属性

    CSS字体属性与文本属性 1. 字体属性 1.1 字体系列font-family p { font-family: "Microsoft Yahei";/*微软雅黑*/ } /*当 ...