zoukankan      html  css  js  c++  java
  • 【BZOJ 1449】 1449: [JSOI2009]球队收益 (最小费用流)

    1449: [JSOI2009]球队收益

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 841  Solved: 483

    Description

    Input

    Output

    一个整数表示联盟里所有球队收益之和的最小值。

    Sample Input

    3 3
    1 0 2 1
    1 1 10 1
    0 1 3 3
    1 2
    2 3
    3 1

    Sample Output

    43

    HINT

    Source

    【题意】

     给定n支球队,第i支球队已经赢了win[i]场,输了lose[i]场,接下来还有m场比赛,每个球队最终的收益为Ci∗x[i]^2+Di∗y[i]^2,其中x[i]为最终的胜场,y[i]为最终的负场,求最小化收益。

    【分析】

      先差分,再拆边。

      注意,输赢都有贡献,普通做法不行。直接当成那些比赛所有人都输,那只要计算赢的那个人的贡献。

      然后差分:

      赢k-1场:c[i]*(win[i]+(k-1))^2+d[i]*(sm[i]+lose[i]-(k-1))^2

      赢k场:c[i]=(win[i]+k)^2+d[i]*(sm[i]+lose[i]-k)^2

      相减得到赢第k场:c[i]*(2*win[i]-(2*k-1))-d[i]*(2*(lose[i]+sm[i])-(2*k-1))

      这是单调的,所以把原本的贡献+最大费用流就好了。

      可以膜Po姐:http://blog.csdn.net/PoPoQQQ/article/details/46619517

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 5010
      9 #define Maxm 1010
     10 #define INF 0xfffffff
     11 
     12 int mymin(int x,int y) {return x<y?x:y;}
     13 
     14 int win[Maxn],lose[Maxn],c[Maxn],d[Maxn],sm[Maxn];
     15 
     16 struct node
     17 {
     18     int x,y,f,c,o,next;
     19 }t[Maxm*100];
     20 int len,first[Maxn*2];
     21 
     22 void ins(int x,int y,int f,int c)
     23 {
     24     t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c;
     25     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     26     t[++len].x=y;t[len].y=x;t[len].f=0;t[len].c=-c;
     27     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     28 }
     29 
     30 queue<int > q;
     31 int st,ed;
     32 int flow[Maxn*2],pre[Maxn*2],dis[Maxn*2];
     33 bool inq[Maxn*2];
     34 bool bfs()
     35 {
     36     while(!q.empty()) q.pop();
     37     // memset(dis,-1,sizeof(dis));
     38     for(int i=1;i<=ed;i++) dis[i]=INF;
     39     memset(inq,0,sizeof(inq));
     40     flow[st]=INF;q.push(st);dis[st]=0;
     41     inq[st]=1;
     42     while(!q.empty())
     43     {
     44         int x=q.front();
     45         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     46         {
     47             int y=t[i].y;
     48             if(dis[y]>dis[x]+t[i].c)
     49             {
     50                 dis[y]=dis[x]+t[i].c;
     51                 pre[y]=i;
     52                 flow[y]=mymin(flow[x],t[i].f);
     53                 if(!inq[y])
     54                 {
     55                     q.push(y);
     56                     inq[y]=1;
     57                 }
     58             }
     59         }
     60         q.pop();inq[x]=0;
     61     }
     62     if(dis[ed]==INF) return 0;
     63     return 1;
     64 }
     65 
     66 int sum=0;
     67 int max_flow()
     68 {
     69     while(bfs())
     70     {
     71         int x=ed;
     72         sum+=flow[ed]*dis[ed];
     73         int a=flow[ed];
     74         while(x!=st)
     75         {
     76             t[pre[x]].f-=a;
     77             t[t[pre[x]].o].f+=a;
     78             x=t[pre[x]].x;
     79         }
     80     }
     81     printf("%d
    ",sum);
     82 }
     83 
     84 void output()
     85 {
     86     for(int i=1;i<=len;i+=2)
     87      printf("%d -> %d %d %d
    ",t[i].x,t[i].y,t[i].f,t[i].c);
     88 }
     89 
     90 int main()
     91 {
     92     int n,m;
     93     scanf("%d%d",&n,&m);
     94     for(int i=1;i<=n;i++) scanf("%d%d%d%d",&win[i],&lose[i],&c[i],&d[i]);
     95     st=n+m+1;ed=st+1;
     96     memset(sm,0,sizeof(sm));
     97     for(int i=1;i<=m;i++)
     98     {
     99         int x,y;
    100         scanf("%d%d",&x,&y);
    101         ins(x,n+i,1,0);
    102         ins(y,n+i,1,0);
    103         ins(n+i,ed,1,0);
    104         sm[x]++;sm[y]++;
    105     }
    106     for(int i=1;i<=n;i++)
    107     {
    108         for(int j=1;j<=sm[i];j++) ins(st,i,1,c[i]*(2*win[i]+2*j-1)-d[i]*(2*(sm[i]+lose[i])-(2*j-1)));
    109         sum+=c[i]*win[i]*win[i]+d[i]*(lose[i]+sm[i])*(lose[i]+sm[i]);
    110     }
    111     max_flow();
    112     return 0;
    113 }
    View Code

    2017-04-01 08:20:09

  • 相关阅读:
    解决类似 /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found 的问题
    qemu vm setup network(ssh) with buildroot
    C: 当字符数组首指针转化成char *指针,sizeof(*ptr)不为array的size
    C 利用strtok, feof 截取字符串
    LINUX C: 获取本地指定网卡的IP地址
    C语言比较好的风格梳理
    perf-perf stat用户层代码分析
    内核调试-perf introduction
    内核调试-ftrace introduction
    【原创】VB6.0应用程序安装包的生成(Setup Factory 9.0制作安装包的方法)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6654405.html
Copyright © 2011-2022 走看看