$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;
}
DFS

相关文章: