zoukankan      html  css  js  c++  java
  • BZOJ 3996 [TJOI 2015] 线性代数 解题报告

    首先,我们可以得到:

    $$D = sum_{i=1}^{n}sum_{j=1}^{n}a_i imes a_j imes b_{i,j} - sum_{i=1}^{n}a_i imes c_i$$

    那么是不是就相当于这样的问题:

    有 $n$ 个物品,你可以选择一些物品出来,如果同时选了 $i,j$ 两个物品那么就有 $b_{i,j}$ 的收益,然而每一个物品都有一个代价 $c_i$,求最大收益。

    这是经典的最小割模型:

    • 连边 $S o Dot(i,j)$,流量为 $b_{i,j}$。
    • 连边 $Dot(i,j) o i$ 以及 $Dot(i,j) o j$,流量为 $infty$。
    • 连边 $i o T$,流量为 $c_i$

    设最小割为 $x$,那么答案就是:

    $$sum_{i=1}^{n}sum_{j=1}^{n}b_{i,j} - x$$

    尽管有很多个点,但还是可以跑得很快的。(*^_^*)

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long LL;
     8 #define N 250000 + 500 + 5
     9 #define M 2500000 + 5
    10 #define INF 0x7fffffff
    11 
    12 int n, S, T, cnt, tot = 1;
    13 int Head[N], q[N], Dfn[N];
    14 LL ans;
    15 
    16 struct Edge
    17 {
    18     int next, node, flow;
    19 }h[M];
    20 
    21 inline void addedge(int u, int v, int fl)
    22 {
    23     h[++ tot].next = Head[u], Head[u] = tot;
    24     h[tot].node = v, h[tot].flow = fl;
    25     h[++ tot].next = Head[v], Head[v] = tot;
    26     h[tot].node = u, h[tot].flow = 0;
    27 }
    28 
    29 inline bool BFS()
    30 {
    31     for (int i = S; i <= T; i ++)
    32         Dfn[i] = 0;
    33     int l = 1, r = 1;
    34     q[1] = S, Dfn[S] = 1;
    35     while (l <= r)
    36     {
    37         int z = q[l ++];
    38         for (int i = Head[z]; i; i = h[i].next)
    39         {
    40             int d = h[i].node, p = h[i].flow;
    41             if (!p || Dfn[d]) continue ;
    42             Dfn[d] = Dfn[z] + 1;
    43             q[++ r] = d;
    44             if (d == T) return 1;
    45         }
    46     }
    47     return 0;
    48 }
    49 
    50 inline int dinic(int z, int inflow)
    51 {
    52     if (z == T) return inflow;
    53     int ret = inflow, flow;
    54     for (int i = Head[z]; i; i = h[i].next)
    55     {
    56         int d = h[i].node, p = h[i].flow;
    57         if (Dfn[d] != Dfn[z] + 1 || !p) continue ;
    58         flow = dinic(d, min(p, ret));
    59         ret -= flow;
    60         h[i].flow -= flow, h[i ^ 1].flow += flow;
    61         if (!ret) return inflow;
    62     }
    63     if (ret == inflow) Dfn[z] = -1;
    64     return inflow - ret;
    65 }
    66 
    67 int main()
    68 {
    69     #ifndef ONLINE_JUDGE
    70         freopen("3996.in", "r", stdin);
    71         freopen("3996.out", "w", stdout);
    72     #endif
    73     
    74     scanf("%d", &n);
    75     S = 0, T = n + n * n + 1, cnt = n;
    76     for (int i = 1; i <= n; i ++)
    77         for (int j = 1, w; j <= n; j ++)
    78         {
    79             scanf("%d", &w);
    80             addedge(S, ++ cnt, w);
    81             addedge(cnt, i, INF);
    82             addedge(cnt, j, INF);
    83             ans += w;
    84         }
    85     for (int i = 1, w; i <= n; i ++)
    86     {
    87         scanf("%d", &w);
    88         addedge(i, T, w);
    89     }
    90     while (BFS())
    91         ans -= dinic(S, INF);
    92     printf("%lld
    ", ans);
    93     
    94     #ifndef ONLINE_JUDGE
    95         fclose(stdin);
    96         fclose(stdout);
    97     #endif
    98     return 0;
    99 }
    3996_Gromah
  • 相关阅读:
    Querying for Event Information
    通过注册表查询 .Net Framework 的版本
    [Batch脚本] if else 的格式
    逆天技能
    财运是靠自己争取的,而财商是可以通过后天学习提高的
    必须冒着可能付出惨痛代价的风险前进,否则你就只能永远做个井底之蛙
    财商低的六种表现
    中国大唐集团公司 主要经营范围
    中国大唐集团公司是2002年12月29日在原国家电力公司部分企事业单位基础上组建而成的特大型发电企业集团
    中国大唐集团公司在役及在建资产分布在全国31个省区市以及境外
  • 原文地址:https://www.cnblogs.com/gromah/p/4451620.html
Copyright © 2011-2022 走看看