[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}}{\sum_{i=1}^{n}b_{i,p_i}}\)。

sol

分数规划。
二分一个答案\(mid\),把所有匹配边的权值设为\(a_{i,j}-mid*b_{i,j}\)。
接下来就是要求是否存在一个权值和大于\(0\)的完美匹配。
费用流直接上了。跑的好慢啊qaq

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 105;
const double eps = 1e-8;
struct edge{int to,nxt,w;double cost;}G[N*N<<2];
int n,a[N][N],b[N][N],head[N<<1],cnt,S,T,vis[N<<1],pe[N<<1];
double dis[N<<1],ans;queue<int>Q;
void link(int u,int v,int w,double cost){
    G[++cnt]=(edge){v,head[u],w,cost};head[u]=cnt;
    G[++cnt]=(edge){u,head[v],0,-cost};head[v]=cnt;
}
bool spfa(){
    memset(dis,0xfe,sizeof(dis));
    dis[S]=0;Q.push(S);
    while (!Q.empty()){
        int u=Q.front();Q.pop();
        for (int e=head[u];e;e=G[e].nxt){
            int v=G[e].to;
            if (G[e].w&&dis[v]<dis[u]+G[e].cost){
                dis[v]=dis[u]+G[e].cost;pe[v]=e;
                if (!vis[v]) vis[v]=1,Q.push(v);
            }
        }
        vis[u]=0;
    }
    if (dis[T]==dis[0]) return false;
    ans+=dis[T];
    for (int i=T;i!=S;i=G[pe[i]^1].to)
        --G[pe[i]].w,++G[pe[i]^1].w;
    return true;
}
bool check(double k){
    memset(head,0,sizeof(head));cnt=1;
    for (int i=1;i<=n;++i) link(S,i,1,0),link(i+n,T,1,0);
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            link(i,j+n,1,(double)a[i][j]-k*b[i][j]);
    ans=0;
    while (spfa()) ;
    return ans>-eps;
}
int main(){
    n=gi();S=2*n+1;T=S+1;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            a[i][j]=gi();
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            b[i][j]=gi();
    double l=0,r=10000;
    while (r-l>eps){
        double mid=(l+r)/2;
        if (check(mid)) l=mid;
        else r=mid;
    }
    printf("%.6lf\n",l);
    return 0;
}

原文地址:https://www.cnblogs.com/zhoushuyu/p/9060714.html

时间: 2024-11-08 21:01:44

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

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

[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]新生舞会 分数规划+费用流

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

bzoj 4819: [Sdoi2017]新生舞会

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

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=(rea

[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还需要考虑两个人一起跳舞是否方便, 比如身高体重差别会不会