• [SDOI2017]新生舞会


    题目描述

    学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴。

    个男生和个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴。

    Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 

    Cathy还需要考虑两个人一起跳舞是否方便,比如身高体重差别会不会太大,计算得出 ,表示第i个男生和第j个女生一起跳舞时的不协调程度。

    当然,还需要考虑很多其他问题。

    Cathy想先用一个程序通过求出一种方案,再手动对方案进行微调。

    Cathy找到你,希望你帮她写那个程序。

    一个方案中有n对舞伴,假设没对舞伴的喜悦程度分别是,假设每对舞伴的不协调程度分别是。令

    Cathy希望C值最大。

    输入输出格式

    输入格式:

    第一行一个整数n。

    接下来n行,每行n个整数,第i行第j个数表示

    接下来n行,每行n个整数,第i行第j个数表示

    输出格式:

    一行一个数,表示C的最大值。四舍五入保留6位小数,选手输出的小数需要与标准输出相等。

    输入输出样例

    输入样例#1:
    3
    19 17 16
    25 24 23
    35 36 31
    9 5 6
    3 4 2
    7 8 9
    输出样例#1:
    5.357143

    说明

    对于10%的数据,

    对于40%的数据,

    另有20%的数据,

    对于100%的数据,

    思路:二分答案+费用流

    一开始,边的费用没有想到,其实移一下项就好了。

    然后,就见识到了什么叫卡常数,蒟蒻常数巨大。。。

    于是就开始借鉴大佬的优化,发现大佬写的是紫书上的板子,果然,手模代码不靠谱吗?

    丧失OI路的信心。

    事实证明:结构体是极慢的。

     7.3s->4.1s

    代码实现:

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define inf -1e9
     5 using namespace std;
     6 const int maxn=110;
     7 const int maxm=maxn*maxn<<2;
     8 queue<int>q;
     9 int n,s,t,a,b;
    10 double l,r,mid,ans,error=1e-7;
    11 int map[maxn][maxn][2],h[maxn*maxn<<1],hs=1;
    12 int e_q[maxm],e_z[maxm],e_n[maxm],p[maxn<<1];
    13 bool e_w[maxm],v[maxn<<1];
    14 double e_f[maxm],w[maxn<<1];
    15 char r_w[30],r_l;
    16 int read(int &x){
    17     while(r_w[0]=getchar(),r_w[0]<'0'||r_w[0]>'9');r_l=1;
    18     while(r_w[r_l]=getchar(),r_w[r_l]>='0'&&r_w[r_l]<='9') r_l++;
    19     for(int i=0;i<r_l;i++) x=x*10+r_w[i]-'0';
    20 }
    21 inline int min_(int x,int y){return x<y?x:y;}
    22 void add(int x,int y,double z){
    23     ++hs,e_q[hs]=x,e_z[hs]=y,e_n[hs]=h[x],e_w[hs]=true,e_f[hs]=z,h[x]=hs;
    24     ++hs,e_q[hs]=y,e_z[hs]=x,e_n[hs]=h[y],e_w[hs]=false,e_f[hs]=-z,h[y]=hs;
    25 }
    26 void MCMF(){
    27     while(1){
    28         for(int i=0;i<=t;i++) w[i]=inf;
    29         memset(v,0,sizeof(v));
    30         q.push(s),w[s]=false;
    31         while(!q.empty()){
    32             a=q.front(),q.pop(),v[a]=0;
    33             for(int i=h[a];i;i=e_n[i])
    34             if(e_w[i]&&w[e_z[i]]<e_f[i]+w[a]){
    35                 b=e_z[i],p[b]=i;
    36                 w[b]=e_f[i]+w[a];
    37                 if(!v[b]) q.push(b),v[b]=true;
    38             }
    39         }
    40         if(w[t]==inf||(ans<0&&w[t]<0)) return;
    41         else ans+=w[t];
    42         for(int i=t;i!=s;i=e_q[p[i]]) e_w[p[i]]=false,e_w[p[i]^1]=true;
    43     }
    44 }
    45 int main(){
    46     read(n);
    47     s=0,t=n*2+1;
    48     for(int i=1;i<=n;i++)
    49     for(int j=1;j<=n;j++)
    50     read(map[i][j][0]);
    51     for(int i=1;i<=n;i++)
    52     for(int j=1;j<=n;j++)
    53     read(map[i][j][1]);
    54     l=0,r=1e4;
    55     while(r-l>error){
    56         mid=(l+r)/2,ans=0;
    57         memset(h,0,sizeof(h)),hs=1;
    58         for(int i=1;i<=n;i++) add(s,i,0),add(i+n,t,0);
    59         for(int i=1;i<=n;i++)
    60         for(int j=1;j<=n;j++)
    61         add(i,j+n,map[i][j][0]-mid*map[i][j][1]);
    62         MCMF();
    63         if(ans>0) l=mid;
    64         else r=mid;
    65     }
    66     printf("%.6lf",r);
    67     return 0;
    68 }

    傻逼题我都改了这么久,药丸药丸。

  • 相关阅读:
    Spring Boot (20) 拦截器
    Spring Boot (19) servlet、filter、listener
    Spring Boot (18) @Async异步
    Spring Boot (17) 发送邮件
    Spring Boot (16) logback和access日志
    Spring Boot (15) pom.xml设置
    Spring Boot (14) 数据源配置原理
    Spring Boot (13) druid监控
    Spring boot (12) tomcat jdbc连接池
    Spring Boot (11) mybatis 关联映射
  • 原文地址:https://www.cnblogs.com/J-william/p/6736129.html
Copyright © 2020-2023  润新知