[01分数规划]【学习笔记】

01分数规划

$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

 

最大权密度子图

$Maximize D=\frac{\sum\limits_{e \in E}x_e}{\sum\limits_{v \in V}x_v}$
$x_e,x_v \in {0,1}$
$\forall e=(u,v) \in E,\ u,v \in V$


同样二分答案$g$,然后判断
$\sum\limits_{e \in E}x_e\ -\ \sum\limits_{v \in V}x_v*g\ >\ 0$则可以更优
二分查找范围$[m,\frac{1}{n}]$,精度$\frac{1}{n^2}$
求解二分查找后式子的最大值使用最大权闭合子图,选一条边则必须选择两个顶点
$s--1-->e--INF-->u,v--g-->t$

posted @ 2017-02-22 19:16  Candy?  阅读(326)  评论(0编辑  收藏  举报