博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】1690: [Usaco2007 Dec]奶牛的旅行
阅读量:6244 次
发布时间:2019-06-22

本文共 1891 字,大约阅读时间需要 6 分钟。

【算法】01分数规划-最优比率环

【题意】给定有向图,点有收益,边有代价,重复经过的话收益不叠加而代价叠加,求从任意点开始最后回归该点的(收益/代价)最大。

【题解】

和普通的分数规划不同,这里的方案选择必须是一个环。首先有一个重要的结论:答案一定是一个简单环

(简单证明:假设当前复杂环为两个简单环有一点重复(该点收益S),令x1/y1>x2/y2,总环是(x1+x2-S)/(y1+y2),即要证x1/y1>(x1+x2-S)/(y1+y2),将式子展开并代入第一个式子即可得证)

由于是一个简单环,每条边就放一个端点的收益即可。二分答案,将-d[i]赋值到每条边上,然后spfa判负环。

 

然后是spfa判断负环。

使用DFS的spfa:可以在发现更新到之前更新过的节点就认为是负环(从x跑出去最后又回来更新x,说明跑的这段路是负数)。

spfa的d数组(最短路)全部初始化为0(即只更新路径为负的),相当于设置一个起点向所有点连容量为0的边,因为是全图找负环。

只要能访问到负环上的一个点,就一定能找出整个负环。

确认某个曾访问的节点是祖先,这是DFS的特性和优势。

已经更新过的d不改回,这样可以保证最坏复杂度就是全图进行一次spfa。

#include
#include
#include
#include
using namespace std;const int maxn=1010,maxM=5010;struct edge{
int v,from;double w;}e[maxM];int first[maxn],tot,a[maxn],b[maxM],n,m;double d[maxn];bool vis[maxn],ok;int read(){ char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c=='-')t=-1; do{s=s*10+c-'0';}while(isdigit(c=getchar())); return s*t;}void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}void spfa(int x){ if(ok)return; vis[x]=1; for(int i=first[x];i;i=e[i].from)if(d[e[i].v]>d[x]+e[i].w){ if(vis[e[i].v]){ok=1;break;} d[e[i].v]=d[x]+e[i].w; spfa(e[i].v); } vis[x]=0;}bool check(double L){ for(int i=1;i<=tot;i++)e[i].w=L*b[i]-a[e[i].v]; memset(d,0,sizeof(d)); //memset(vis,0,sizeof(vis));// ok=0; for(int i=1;i<=n;i++){ spfa(i); if(ok)return 1; } return 0;}int main(){ n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); int u,v,w; for(int i=1;i<=m;i++){ u=read();v=read();w=read(); insert(u,v); b[i]=w; } double l=0,r=10100,mid;// while(r-l>1e-3){ mid=(l+r)/2; if(check(mid))l=mid; else r=mid; } printf("%.2lf",l); return 0;}
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/7452937.html

你可能感兴趣的文章
《算法导论》读书笔记之第15章 动态规划—最长公共子序列
查看>>
从$a_n=f(n)$的角度理解数列中的表达式$a_{n+1}=\frac{k}{a_n}$
查看>>
Redis以及Redis的php扩展安装无错版
查看>>
总结性博客作业
查看>>
Windows Phone 8初学者开发—第11部分:设置SounBoard应用程序
查看>>
欧拉图和哈密顿图
查看>>
解线性方程组
查看>>
Python:pandas之DataFrame常用操作
查看>>
Appium移动自动化测试之—基于java的iOS环境搭建
查看>>
NOIP前的刷题记录
查看>>
洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)
查看>>
书签(Bookmarks)
查看>>
Java 信号量 Semaphore 介绍
查看>>
Ubuntu常用软件安装与使用
查看>>
Anroid开发中常用快捷键
查看>>
RecyclerView分隔线定制
查看>>
文本处理(CSS,JS)
查看>>
VBScript 函数
查看>>
shell编程学习
查看>>
java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I错误解决
查看>>