作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司。这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j。当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得他的花费,那么作为一个聪明的人,小L当然不会雇佣他。 然而,那些没有被雇佣的人会被竞争对手所雇佣,这个时候那些人会对你雇佣的经理的工作造成影响,使得所赚得的利润减少Ei,j(注意:这里的Ei,j与上面的Ei,j 是同一个)。 作为一个效率优先的人,小L想雇佣一些人使得净利润最大。你可以帮助小L解决这个问题吗?
第一行有一个整数N<=1000表示经理的个数 第二行有N个整数Ai表示雇佣每个经理需要花费的金钱 接下来的N行中一行包含N个数,表示Ei,j,即经理i对经理j的了解程度。(输入满足Ei,j=Ej,i)
1 #include <cstdio>
2 #include <cstring>
3
4 const int siz = 4000010;
5 const int inf = 1000000007;
6
7 int n;
8
9 int tot;
10 int s, t;
11 int hd[siz];
12 int to[siz];
13 int fl[siz];
14 int nt[siz];
15
16 inline void add(int u, int v, int f)
17 {
18 // printf("add %d %d %d\n", u, v, f);
19 nt[tot] = hd[u]; to[tot] = v; fl[tot] = f; hd[u] = tot++;
20 nt[tot] = hd[v]; to[tot] = u; fl[tot] = 0; hd[v] = tot++;
21 }
22
23 int dep[siz];
24
25 inline bool bfs(void)
26 {
27 static int que[siz];
28 static int head, tail;
29
30 memset(dep, 0, sizeof(dep));
31 dep[que[head = 0] = s] = tail = 1;
32
33 while (head != tail)
34 {
35 int u = que[head++], v;
36 for (int i = hd[u]; ~i; i = nt[i])
37 if (fl[i] && !dep[v = to[i]])
38 dep[que[tail++] = v] = dep[u] + 1;
39 }
40
41 return dep[t];
42 }
43
44 int cur[siz];
45
46 inline int min(int a, int b)
47 {
48 return a < b ? a : b;
49 }
50
51 int dfs(int u, int f)
52 {
53 if (u == t || !f)
54 return f;
55
56 int used = 0, flow, v;
57
58 for (int i = hd[u]; ~i; i = nt[i])
59 if (fl[i] && dep[v = to[i]] == dep[u] + 1)
60 {
61 flow = dfs(v, min(f - used, fl[i]));
62 used += flow;
63 fl[i] -= flow;
64 fl[i ^ 1] += flow;
65 if (used == f)
66 return f;
67 if (fl[i])
68 cur[u] = i;
69 }
70
71 if (!used)
72 dep[u] = 0;
73
74 return used;
75 }
76
77 inline int maxFlow(void)
78 {
79 int maxFlow = 0, newFlow;
80
81 while (bfs())
82 {
83 for (int i = s; i <= t; ++i)
84 cur[i] = hd[i];
85
86 while (newFlow = dfs(s, inf))
87 maxFlow += newFlow;
88 }
89
90 return maxFlow;
91 }
92
93 int ans;
94 int sum;
95
96 signed main(void)
97 {
98 scanf("%d", &n);
99
100 s = 0, t = n + 1;
101
102 memset(hd, -1, sizeof(hd));
103
104 for (int i = 1, x; i <= n; ++i)
105 scanf("%d", &x), add(s, i, x);
106
107 for (int i = 1; i <= n; ++i)
108 {
109 sum = 0;
110
111 for (int j = 1; j <= n; ++j)
112 {
113 int x; scanf("%d", &x);
114 ans += x;
115 sum += x;
116 if (i != j)
117 add(i, j, x << 1);
118 }
119
120 add(i, t, sum);
121 }
122
123 printf("%d\n", ans - maxFlow());
124 }