就是求$D = A \times B \times A^T - C \times A^T$

展开也就是$$D = \sum_{i, j} A_i * A_j * B_{i, j} - \sum_{i} C_i * A_i$$

其中$Ai = 0 \ or \ 1$

转化成最小割模型,就是一堆东西,选了$i$号物品要支付费用$C_i$,同时选$i$和$j$两个物品可以获得$B_{i, j}$的收益

于是非常简单啦,建图什么的直接看程序好了!

 

 1 /**************************************************************
 2     Problem: 3996
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:476 ms
 7     Memory:51612 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 505 * 505;
16 const int M = N << 4;
17 const int inf = 1e9;
18  
19 struct edge {
20     int next, to, f;
21     edge() {}
22     edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
23 } e[M];
24  
25 int n, ans, S, T;
26 int first[N], tot = 1;
27 int d[N], q[N];
28  
29 inline int read();
30  
31 inline void Add_Edges(int x, int y, int f) {
32     e[++tot] = edge(first[x], y, f), first[x] = tot;
33     e[++tot] = edge(first[y], x, 0), first[y] = tot;
34 }
35  
36 #define y e[x].to
37 #define p q[l]
38 bool bfs() {
39     int l, r, x;
40     memset(d, -1, sizeof(d));
41     d[q[1] = S] = 1;
42     for (l = r = 1; l != r + 1; ++l)
43         for (x = first[p]; x; x = e[x].next)
44             if (!~d[y] && e[x].f) {
45                 d[q[++r] = y] = d[p] + 1;
46                 if (y == T) return 1;
47             }
48     return 0;
49 }
50 #undef p
51  
52 int dfs(int p, int lim) {
53   if (p == T || !lim) return lim;
54   int x, tmp, rest = lim;
55   for (x = first[p]; x && rest; x = e[x].next) 
56     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
57       rest -= (tmp = dfs(y, tmp));
58       e[x].f -= tmp, e[x ^ 1].f += tmp;
59       if (!rest) return lim;
60     }
61   if (rest) d[p] = -1;
62   return lim - rest;
63 }
64 #undef y
65  
66 int Dinic() {
67   int res = 0;
68   while (bfs())
69     res += dfs(S, inf);
70   return res;
71 }
72  
73 int main() {
74     int i, j, x, now;
75     n = now = read(), S = n * n + n + 1, T = S + 1;
76     for (i = 1; i <= n; ++i)
77         for (j = 1; j <= n; ++j) {
78             x = read(), ++now;
79             Add_Edges(i, now, inf), Add_Edges(j, now, inf);
80             Add_Edges(now, T, x);
81             ans += x;
82         }
83     for (i = 1; i <= n; ++i) Add_Edges(S, i, read());
84     printf("%d\n", ans - Dinic());
85     return 0;
86 }
87  
88 inline int read() {
89     static int x;
90     static char ch;
91     x = 0, ch = getchar();
92     while (ch < '0' || '9' < ch)
93         ch = getchar();
94     while ('0' <= ch && ch <= '9') {
95         x = x * 10 + ch - '0';
96         ch = getchar();
97     }
98     return x;
99 }
View Code

 

posted on 2015-04-24 21:51  Xs酱~  阅读(209)  评论(0编辑  收藏  举报