zoukankan      html  css  js  c++  java
  • 洛谷P4307 球队收益

    题意:有n个球队,m场比赛。

    每个球队都已经有些胜负场次了。

    每个球队的收益为Ci * wini2 - Di * losei2

    求最小可能总收益。

    解:

    先看出一个模型:用一流量代表一个胜场,每场比赛向两支队伍连边。

    然后我们发现这个费用是跟流量的平方有关的,How to do?

    先观察一波:1 4 9 16 25

    差分:1 3 5 7 9

    然后我们就发现:如果把下面差分建成边的费用,限流为1,恰好就是收益了。

    至此茅塞顿开。

    首先假设所有的队伍都输了,然后每场选出一名胜者,C(2win + 1) - D(2lose - 1)为费用。

    最小费用最大流即可。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 
      6 const int N = 6050, M = 1000010;
      7 const int INF = 0x3f3f3f3f;
      8 
      9 struct Edge {
     10     int nex, v;
     11     int c, len;
     12 }edge[M << 1]; int top = 1;
     13 
     14 int e[N], vis[N], pre[N];
     15 int d[N], flow[N];
     16 std::queue<int> Q;
     17 int A[N], B[N], C[N], D[N], win[N], los[N], X[N], Y[N];
     18 
     19 inline void add(int x, int y, int z, int w) {
     20     //printf("add : %d %d 
    ", x, y);
     21     top++;
     22     edge[top].v = y;
     23     edge[top].c = z;
     24     edge[top].len = w;
     25     edge[top].nex = e[x];
     26     e[x] = top;
     27 
     28     top++;
     29     edge[top].v = x;
     30     edge[top].c = 0;
     31     edge[top].len = -w;
     32     edge[top].nex = e[y];
     33     e[y] = top;
     34     return;
     35 }
     36 
     37 inline bool SPFA(int s, int t) {
     38     memset(d, 0x3f, sizeof(d));
     39     d[s] = 0;
     40     flow[s] = INF;
     41     vis[s] = 1;
     42     Q.push(s);
     43     while(!Q.empty()) {
     44         int x = Q.front();
     45         Q.pop();
     46         vis[x] = 0;
     47         //printf("x = %d d = %d
    ", x, d[x]);
     48         for(int i = e[x]; i; i = edge[i].nex) {
     49             int y = edge[i].v;
     50             if(edge[i].c && d[y] > d[x] + edge[i].len) {
     51                 d[y] = d[x] + edge[i].len;
     52                 pre[y] = i;
     53                 flow[y] = std::min(flow[x], edge[i].c);
     54                 if(!vis[y]) {
     55                     vis[y] = 1;
     56                     Q.push(y);
     57                 }
     58             }
     59         }
     60     }
     61     return d[t] < INF;
     62 }
     63 
     64 inline void update(int s, int t) {
     65     int temp = flow[t];
     66     while(t != s) {
     67         int i = pre[t];
     68         edge[i].c -= temp;
     69         edge[i ^ 1].c += temp;
     70         t = edge[i ^ 1].v;
     71     }
     72     return;
     73 }
     74 
     75 inline int solve(int s, int t, int &cost) {
     76     int ans = 0;
     77     cost = 0;
     78     while(SPFA(s, t)) {
     79         ans += flow[t];
     80         cost += flow[t] * d[t];
     81         update(s, t);
     82     }
     83     return ans;
     84 }
     85 
     86 int main() {
     87     int n, m, s, t, sum = 0;
     88     scanf("%d%d", &n, &m);
     89     s = n + m + 1, t = m + n + 2;
     90     for(int i = 1; i <= n; i++) {
     91         scanf("%d%d%d%d", &win[i], &los[i], &C[i], &D[i]);
     92         /*win[i] = A[i];
     93         los[i] = B[i];*/
     94     }
     95     for(int i = 1; i <= m; i++) {
     96         scanf("%d%d", &X[i], &Y[i]);
     97         add(s, n + i, 1, 0);
     98         add(n + i, X[i], 1, 0);
     99         add(n + i, Y[i], 1, 0);
    100         los[X[i]]++;
    101         los[Y[i]]++;
    102     }
    103     for(int i = 1; i <= n; i++) {
    104         sum += C[i] * win[i] * win[i];
    105         sum += D[i] * los[i] * los[i];
    106     }
    107     for(int i = 1; i <= m; i++) {
    108         int x = X[i], y = Y[i];
    109         add(x, t, 1, C[x] * (2 * win[x] + 1) - D[x] * (2 * los[x] - 1));
    110         add(y, t, 1, C[y] * (2 * win[y] + 1) - D[y] * (2 * los[y] - 1));
    111         win[x]++;
    112         win[y]++;
    113         los[x]--;
    114         los[y]--;
    115     }
    116 
    117     int ans;
    118     solve(s, t, ans);
    119     printf("%d", ans + sum);
    120     return 0;
    121 }
    AC代码
  • 相关阅读:
    Linux环境部署项目引起Out of Memory Error: PermGen Space的解决方案
    手动上传图片到nginx下可访问,程序上传后访问图片报403
    Spring的断言工具类Assert的基本使用
    前后台分离部署时,Niginx上的部署
    GDAL VS2010 win7(64位)安装、使用说明(图文解析)
    转:libc6-dbg libc库调试的时候需要安装该库获得debug information 才能step into
    转:详解linux中的strings命令简介
    转:浮点数环境 cfenv(fenv.h)
    转:C语言中关于float、double、long double精度及数值范围理解
    转:linux中fork()函数详解
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10115857.html
Copyright © 2011-2022 走看看