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)+(a_2-c*b_2)+(a_3-c*b_3)\)
取反跑费用流就好了
每次cnt没=1,居然T了
说:没油圈就可以取反跑费用流

代码

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 5e5 + 7,inf=0x3f3f3f3f;
const double eps=1e-7;
int read() {
    int x=0,f=1;char s=getchar();
    for (;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for (;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,S,T;
int a[120][119],b[110][120];
struct node {
    int u,v,nxt,cap;
    double cost;
}e[N];
int head[N],cnt=1;
void add_edge(int u,int v,int cap,double cost) {
    e[++cnt].v=v;
    e[cnt].u=u;
    e[cnt].cap=cap;
    e[cnt].cost=cost;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
void Add(int u,int v,int cap,double cost) {
    add_edge(u,v,cap,cost);
    add_edge(v,u,0,-cost);
}
double dis[1001];
int frm[1001];
bool vis[1001];
queue<int> q;
bool spfa() {
    for(int i=0;i<=n+n;++i) dis[i]=-inf;
    dis[T]=-inf;
    memset(vis,0,sizeof(vis));
    memset(frm,0,sizeof(frm));
    q.push(S);
    dis[S]=0;
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt) {
            int v=e[i].v;
            if(e[i].cap&&dis[v]<dis[u]+e[i].cost) {
                dis[v]=dis[u]+e[i].cost;
                frm[v]=i;
                if(!vis[v]) vis[v]=1,q.push(v);
            }
        }
    }
    return dis[T]!=-inf;
}
double work() {
    double ans=0;
    while(spfa()) {
        int now_flow=inf;
        for(int i=frm[T];i;i=frm[e[i].u])
            now_flow=min(now_flow,e[i].cap);
        for(int i=frm[T];i;i=frm[e[i].u]) {
            e[i].cap-=now_flow;
            e[i^1].cap+=now_flow;
            ans+=now_flow*e[i].cost;
        }
    }
    return ans;
}
bool check(double c) {
    memset(e,0,sizeof(e));
    memset(head,0,sizeof(head));
    cnt=1;
    S=2*n+1,T=2*n+2;
    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,a[i][j]-c*b[i][j]);
    double tmp=work();
    return tmp>=eps;//精度高了,等不等号差不多了
}
int main() {
    //read
    n=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            a[i][j]=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            b[i][j]=read();
    double l=0,r=1e4+1,ans=0;
    while(r-l>=eps) {
        double mid=(l+r)/2;
        if(check(mid)) ans=mid,l=mid;
        else r=mid;
    }
    printf("%.6lf\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/dsrdsr/p/10387145.html

时间: 2024-11-08 20:29:05

4819: [Sdoi2017]新生舞会的相关文章

bzoj 4819: [Sdoi2017]新生舞会

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

[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}}

【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

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

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