[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; }
最大权密度子图
$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$