codevs 5965 [SDOI2017]新生舞会

分数规划的裸题。

不会分数规划的OIer。百度:胡伯涛《最小割模型在信息学竞赛中的应用》

/*
TLE1:
last:add(i,j+n,1e9,(real)((real)a[i][j]-ans*(real)b[i][j]));
now :add(i,j+n,1,(real)((real)a[i][j]-ans*(real)b[i][j]));
TLE2:
last:real l=eps,r=(real)u/(real)v,mid,ans=0,now;
now :real l=0,r=(real)(u+v-1)/(real)v,mid,ans=0,now;
TLE3:
last:struct edge{int v,next;real cost,cap;}e[N<<1];
now :to[N],next[N],cap[N];real cost[N];(结构体跑得慢)
TLE4:
last:typedef long double real;
now :typedef double real;
*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define set(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
const int N=1e5+5;
const int Z=105;
typedef long double real;
const real eps=1e-8;
int n,m,S,T,a[Z][Z],b[Z][Z];
int to[N],next[N],cap[N];real cost[N];int tot=1,head[N];
real dis[N];int q[N],pre[N];bool vis[N];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
void add(int x,int y,int z,real Cost){
    to[++tot]=y;cap[tot]=z;cost[tot]=Cost;next[tot]=head[x];head[x]=tot;
    to[++tot]=x;cap[tot]=0;cost[tot]=-Cost;next[tot]=head[y];head[y]=tot;
}
bool spfa(){
    memset(vis,0,sizeof vis);
    for(int i=0;i<=T+10;i++) dis[i]=-1e9;
    unsigned short h=0,t=1;q[t]=S;dis[S]=0;
    while(h!=t){
        int x=q[++h];vis[x]=0;
        for(int i=head[x];i;i=next[i]){
            if(cap[i]>0&&dis[to[i]]<dis[x]+cost[i]){
                dis[to[i]]=dis[x]+cost[i];
                pre[to[i]]=i;
                if(!vis[to[i]]){
                    vis[to[i]]=1;
                    q[++t]=to[i];
                }
            }
        }
    }
    return dis[T]>-1e9;
}
real augment(){
//    int flow=1e9;
//    for(int i=T;i!=S;i=to[pre[i]^1]) flow=min(flow,cap[pre[i]]);
    int flow=1;
    for(int i=T;i!=S;i=to[pre[i]^1]){
        cap[pre[i]]-=flow;
        cap[pre[i]^1]+=flow;
    }
    return dis[T]*flow;
}
real mapping(real ans){
    tot=1;S=0;T=n<<1|1;
    memset(head,0,sizeof head);
    for(int i=1;i<=n;i++) add(S,i,1,0),add(i+n,T,1,0);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            add(i,j+n,1,(real)((real)a[i][j]-ans*(real)b[i][j]));
        }
    }
    real res=0.0;
    while(spfa()) res+=augment();
    return res;
}
int cmp(real x){
    if(fabs(x)<eps) return 0;
    return x>0?1:-1;
}
void work1(){
    tot=1;S=0;T=n<<1|1;
    memset(head,0,sizeof head);
    for(int i=1;i<=n;i++) add(S,i,1,0),add(i+n,T,1,0);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            add(i,j+n,1,(real)a[i][j]);
        }
    }
    real res=0.0;
    while(spfa()) res+=augment();
    res/=1.0*n;
    printf("%.6lf\n",(double)res);
}
int main(){
    set(ball);
    n=read();
    int u=0,v=0;
    for(int i=1,t;i<=n;i++){
        t=0;
        for(int j=1;j<=n;j++){
            a[i][j]=read();
            t=max(t,a[i][j]);
        }
        u+=t;
    }
    bool f=1;
    for(int i=1,t;i<=n;i++){
        t=1e9;
        for(int j=1;j<=n;j++){
            b[i][j]=read();
            t=min(t,b[i][j]);
            if(b[i][j]!=1) f=0;
        }
        v+=t;
    }
    if(f){work1();return 0;}
    real l=0,r=(real)(u+v-1)/(real)v,mid,ans=0,now;
    while(l+eps<r){
        mid=(l+r)/2.0;
        now=mapping(mid);
        if(cmp(now)==0){printf("%.6lf\n",(double)mid);return 0;}
        if(cmp(now)>0) l=mid;
        else r=mid;
    }
    printf("%.6lf\n",(double)l);
    fclose(stdin);
    fclose(stdout);
    return 0;
}
时间: 2024-10-15 22:24:17

codevs 5965 [SDOI2017]新生舞会的相关文章

[Sdoi2017]新生舞会

[Sdoi2017]新生舞会 http://www.lydsy.com/JudgeOnline/problem.php?id=4819 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人之前认识没计算

[BZOJ4819][SDOI2017]新生舞会

[BZOJ4819][SDOI2017]新生舞会 bzoj luogu 题意 有\(n\)个男孩子和\(n\)个女孩子.他们之间要两两结伴跳舞. 已知第\(i\)个男孩子和第\(j\)个女孩子结伴跳舞会有两个参数\(a_{i,j}\)和\(b_{i,j}\). 现在要求一个安排方案使得\(a_{i,j}\)的总和除以\(b_{i,j}\)的总和的商尽量大. 形式化地,就是求一个长度为\(n\)的排列\(\{p_i\}\),最大化\(L=\frac{\sum_{i=1}^{n}a_{i,p_i}}

bzoj 4819: [Sdoi2017]新生舞会

Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度.Cathy还需要考虑两个人一起跳舞是否方便, 比如身高体重差别会不会太大,计算得出 b[i][j],表示第i个男生和第j个女生一起跳舞时的不协调程度.当然, 还需要考虑很多其他问题.Cathy

【bzoj4819】[Sdoi2017]新生舞会 分数规划+费用流

题目描述 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度.Cathy还需要考虑两个人一起跳舞是否方便,比如身高体重差别会不会太大,计算得出 b[i][j],表示第i个男生和第j个女生一起跳舞时的不协调程度.当然,还需要考虑很多其他问题.Cathy想先用一个程序通过a

BZOJ4819: [Sdoi2017]新生舞会(01分数规划)

Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1029  Solved: 528[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度.Cathy

[Libre][SDOI2017]新生舞会

分数规划模板题 , 会写就能A #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<map> #include<queue> #include<vector> #include<cstdio> using namespace std; typedef long long ll; const int N

4819: [Sdoi2017]新生舞会

题目 https://www.lydsy.com/JudgeOnline/problem.php?id=4819 思路 分数规划的模板题?(好菜呀) 假如n=3吧(懒得写很长的式子) \(c=\frac{a_1+a_2+a_3}{b_1+b_2+b_3}\) 我们先二分一下,变为判定性问题 c是否大于等于xxxx \(c>=\frac{a_1+a_2+a_3}{b_1+b_2+b_3}\) \((b_1+b_2+b_3)*c>=a_1+a_2+a_3\) \(0>=(a_1-c*b_1)

P3705 [SDOI2017]新生舞会 分数规划 费用流

#include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #incl

BZOJ4819 新生舞会

4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MB Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度.Cathy还需要考虑两个人一起跳舞是否方便, 比如身高体重差别会不会