[USACO07DEC] Sightseeing Cows G(分数规划+负权回路判定)

news/2025/3/4 16:51:59/

题面

[USACO07DEC] Sightseeing Cows G - 洛谷

题目大意:

给出一张n点m边的带点权带边权的有向图

求一个回路使得路上点权和除以边权和最大(最优比率回路)

题解

首先一定仔细读题,是回路不是路径

由于回路上所有点权只能获取一次,但边权会获取很多次,所以最优解一定是简单回路(无重复边)

然后我们发现是让一个分数最大,于是我们可以考虑分数规划二分

假设二分的商为mid,判断是否存在一个满足点边权和比大于mid的回路,则二分判断条件为

\sum_{u\in V_p}valv[u]/\sum_{e\in E_p}vale[e]> mid(Vp为最优简单回路的点集,Ep为最优简单回路的边集)

稍微变换一下形式

\sum_{u\in V_p}valv[u]-mid*\sum_{e\in E_p}vale[e]> 0

这个判断条件依旧不好计算,因为我们二分的目的就是为了把最优化问题转换为判断性问题,但是对于该条件,我们除了枚举所有的简单回路,没有任何切入点

转念一想,最后这个大于0似乎暗藏玄机,又和回路联系在一起

不由得让人想到判断图是否存在正权回路(可以直接取相反数转化为判断负权回路)

为了把问题往这个方向转,我们尝试把点权下放到边权

\sum_{e=<u,v>\in E_p}-(valv[v]-mid*vale[e])< 0

把每条边边权设置为 -(它要通往的点的点权-mid*它原本的边权)

但是这样又会有一个新的问题,如果我们最后选出来的回路是这个样子

这样不就会重复计算点权了吗?

事实上这种情况是不存在的

我们可以感性的证明一下:

出现重复点的简单回路,一定可以拆解成若干初级回路(无重复点、无重复边)

整个回路最终的比率一定不会超过其中比率最大的初级回路((a+b)/(c+d)<=max(a/c,b/d),似乎在小学奥数里面叫糖水不等式?)(而且整个回路的比率的分子还会减去重复点的点权)

所以,我们选择一定是选择简单回路里面最优的初级回路

至此,我们就可以下放点权了

愉快地使用SPFA进行负权回路判断

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define N 1005
#define M 10005
#define INF 1000000000
int n,m;
int F[N];
struct enode{int u,v,w;
}E[M];
int fir[N],to[M],nxt[M],cnt;
double cd[M];
void adde(int a,int b,double c)
{to[++cnt]=b;cd[cnt]=c;nxt[cnt]=fir[a];fir[a]=cnt;
}
double dis[N];
int con[N];
bool inq[N];
queue<int> Q;
bool check()
{int i;for(i=1;i<=n;i++)dis[i]=INF;for(i=1;i<=n;i++)con[i]=0;for(i=1;i<=n;i++)inq[i]=0;for(i=1;i<=n;i++){if(dis[i]==INF){dis[i]=0;inq[i]=1;Q.push(i);while(!Q.empty()){int u=Q.front();Q.pop();inq[u]=0;for(int p=fir[u];p;p=nxt[p]){int v=to[p];double w=cd[p];if(dis[u]+w<dis[v]){dis[v]=dis[u]+w;con[v]++;if(!inq[v]){Q.push(v);inq[v]=1;}if(con[v]>=n)return 1;}}}}}return 0;
}
int main()
{int i;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&F[i]);for(i=1;i<=m;i++)scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);double l=0,r=1000,mid;while(r-l>1e-3){mid=(l+r)/2;cnt=0;for(i=1;i<=n;i++)fir[i]=0;for(i=1;i<=m;i++)adde(E[i].u,E[i].v,-(1.0*F[E[i].v]-mid*E[i].w));if(check())l=mid;elser=mid;}printf("%.2f",l);
}


http://www.ppmy.cn/news/1074864.html

相关文章

2023年高教社杯数学建模思路 - 案例:粒子群算法

文章目录 1 什么是粒子群算法&#xff1f;2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法&#xff1f; 粒子群算法&#xff08;Pa…

浅析token

上一章节我们学习了cookie和session机制&#xff0c;但是他们都有一些缺点&#xff0c;所有这次我们来了解一个机制---token。 一、cookie和session的缺点 cookie信息存储在客户端浏览器上&#xff0c;安全性较低&#xff0c;所以浏览器加入了一些限制确保cookie不会被恶意使用…

Windows系统下MMDeploy预编译包的使用

Windows系统下MMDeploy预编译包的使用 MMDeploy步入v1版本后安装/使用难度大幅下降&#xff0c;这里以部署MMDetection项目的Faster R-CNN模型为例&#xff0c;将PyTorch模型转换为ONNX进而转换为Engine模型&#xff0c;部署到TensorRT后端&#xff0c;实现高效推理&#xff0c…

plumelog介绍与应用-一个简单易用的java分布式日志系统

官方文档&#xff1a;http://www.plumelog.com/zh-cn/docs/FASTSTART.html 简介 无代码入侵的分布式日志系统&#xff0c;基于log4j、log4j2、logback搜集日志&#xff0c;设置链路ID&#xff0c;方便查询关联日志基于elasticsearch作为查询引擎高吞吐&#xff0c;查询效率高全…

【业务功能篇90】微服务-springcloud-检索服务-ElasticSearch实战运用-DSL语句

商城检索服务 1.检索页面的搭建 商品检索页面我们放在search服务中处理&#xff0c;首页我们需要在mall-search服务中支持Thymeleaf。添加对应的依赖 <!-- 添加Thymeleaf的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifa…

根据一个List生成另外一个List,修改其中一个,导致另外一个List也在变化

1、两个List复制 SysDic aSysDic new SysDic(); aSysDic.setDkey("1"); aSysDic.setDnote("12"); SysDic bSysDic new SysDic(); bSysDic.setDkey("2"); bSysDic.setDnote("23"); …

node18 vue2启动报错 error:0308010C:digital envelope routines::unsupported

出现原因 貌似是因为是因为 node 17版本开始发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制&#xff0c;可能会对生态系统造成一些影响。 解决方法 第一种方法降低node版本 降低到17以下即可 &#xff0c;如项目不能降低版本 看后面的解决方式 第二…

Oracle-day6:over()函数

目录 一、over()开窗函数 二、无参over()的使用 三、over(partition by 列名) 四、over(order by 列名 asc/desc) 五、over(partition by 列名 order by 列名 asc|desc) 六、练习&#xff08;笔试&#xff09; 一、over()开窗函数 拓展:数据库的版本 oracle:8i 9i 10g …