$N$个物品选$k$个,最大化:
$\frac{\sum\limits_{i=1}^{k}A_i}{\sum\limits_{i=1}^{k}B_i}$
二分答案$mid$
如果
$\sum\limits_{i=1}^{k}{A_i-mid*B_i}\ >\ 0$
则可以更优
显然是要选择$A_i-mid*B_i$的前$k$大
最优比率生成树
最小化生成树的$n$条边
$\frac{\sum\limits_{i,j=1}^{n}cost(i,j)}{\sum\limits_{i,j=1}^{n}Dis(i,j)}$
一样的做法二分答案每次求最小生成树
然后完全图用$Kruskal$多一个$log$,还是用$Prim\ Naive$好(你以为我会告诉你我现学的$Prim$嘛)
最优比率环
找一个环,最大化某个条件
二分答案,在图上转化为负环
$spfa$判断负环:
$1.$普通$BFS$做法,可以先把所有点加到队列里,$d[i]=0$
$2.$$DFS$做法,$d[i]=0$,枚举每个点开始$DFS$,看看会不会形成环
double d[N]; int vis[N],cl; bool dfs(int u,double mid){ vis[u]=cl; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v;double w=mid*e[i].w-f[u]; if(d[v]>d[u]+w){ d[v]=d[u]+w; if(vis[v]==vis[u]) return true; else if(dfs(v,mid)) return true; } } vis[u]=0; return false; } bool NegativeCircle(double mid){ memset(vis,0,sizeof(vis)); for(cl=1;cl<=n;cl++) if(dfs(cl,mid)) return true; return false; }