bzoj4819 [Sdoi2017]新生舞会 分数规划(实数二分)+网络流检验

来源:互联网 发布:网络摄像机安防方案 编辑:程序博客网 时间:2024/05/11 19:37

这个题其实就是二分检验。。

稍微移个项就可以得到(a1-c*b1)+(a2-c*b2)+……

这样贡献就化成了具体到每次决策的影响,c显然满足连续性,所以可以二分c

跑最大流以求得到最大的值使当前答案显得小,就可以得出答案


主要就是化动为静,,如果答案反过来影响过程就可以考虑枚举答案分析,然后来判断当前的影响值 和 作为限度的影响值


注:

1、l和r的eps

2、spfa的返回值

3、double的建边

4、前继一定是-1;


码:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;queue<int>q;#define N 50000int tot=-1,hou[N],xia[N],zhong[N],v[N],s,t,i,j,n,m,qj[N];bool vis[N];double C[N],d[N],l,r,a[105][105],b[105][105],daan,ans;void jian(int a,int b,double c,int d){++tot;hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,C[tot]=c,v[tot]=d;}void jia(int a,int b,double v){jian(a,b,v,1);jian(b,a,-v,0);}bool spfa(){int i;for(i=1;i<=t;i++){d[i]=-99999999;}memset(qj,-1,sizeof(qj));q.push(s);d[s]=0;while(!q.empty()){int st=q.front();q.pop();vis[st]=0;for(i=xia[st];i!=-1;i=hou[i]){int nd=zhong[i];if(!v[i]||d[nd]>=d[st]+C[i])continue;qj[nd]=i;d[nd]=d[st]+C[i];if(vis[nd]==0){vis[nd]=1;q.push(nd);}}}if(d[t]==-99999999)return 0;int o=qj[t],minf=999;while(o!=-1){minf=min(minf,v[o]);o=qj[zhong[o^1]];}o=qj[t];while(o!=-1){ans+=C[o]*(1.00000000*v[o]);v[o]-=minf;v[o^1]+=minf;o=qj[zhong[o^1]];}//cout<<ans<<" ";return 1;}void mcmf(){while(spfa());}int main(){scanf("%d",&n);s=n*n+1;t=n*n+2;for(i=1;i<=n;i++){for(j=1;j<=n;j++){scanf("%lf",&a[i][j]);    }}for(i=1;i<=n;i++){for(j=1;j<=n;j++){scanf("%lf",&b[i][j]);    }}l=0.0000001;r=1000000.0000001;while(l+0.00000001<r){double mid=(l+r)/2;memset(xia,-1,sizeof(xia));tot=-1;for(i=1;i<=n;i++){jia(s,i,0);for(j=1;j<=n;j++){jia(i,n+j,a[i][j]-mid*b[i][j]);}jia(i+n,t,0);    }ans=0;mcmf();//printf("%.8lf  %.8lf\n",mid,ans);if(ans<=0){r=mid;daan=mid;}else l=mid+0.0000001;}printf("%.6lf",daan);}


阅读全文
0 0
原创粉丝点击