HYSBZ 3996 线性代数
题目描述:
输入一个 N×N 的矩阵 B 和一个 1×N 的列向量 C ,求一个 01 矩阵 A ,使得 (A×B−C)×AT 最大(可以证明这是一个 1×1 的矩阵)。输出那个最大的值。
题解:
(A×B−C)×AT=A×B×AT−C×AT=∑i∑jA1,jA1,iBj,i−∑iA1,iC1,i
模型转化,假设有 N 个物品, A1,i 表示第 i 个选不选,选的话去要付出 C1,i 的代价,但如果两个物品 i 和 j 都选就会得到 Bi,j 的收益,问最大收益和是多少。
于是就变成了网络流经典问题。算了一下大概有 3⋅105 个点, 2⋅106 条边,我也不知道为什么能跑的过去……
代码:
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXM = 300007;
const int MAXG = 2000007;
#define encode(i, j) (N * (i) + (j))
#define S (0)
#define T (N * N + N + 1)
const int INF = 0x3f3f3f3f;
static struct
{
int v, w, next;
} edge[MAXG];
static int N, G, sum, head[MAXM], dist[MAXM];
inline void add_edge(int u, int v, int w)
{
edge[G].v = v; edge[G].w = w; edge[G].next = head[u]; head[u] = G++;
edge[G].v = u; edge[G].w = 0; edge[G].next = head[v]; head[v] = G++;
}
inline bool bfs(void)
{
queue<int> Q;
memset(dist, 0, sizeof(dist));
Q.push(S); dist[S] = 1;
while (!Q.empty())
{
int x = Q.front(); Q.pop();
for (int i = head[x]; ~i; i = edge[i].next)
if (edge[i].w && !dist[edge[i].v])
Q.push(edge[i].v), dist[edge[i].v] = dist[x] + 1;
}
return dist[T];
}
int dfs(int x, int f)
{
if (x == T) return f;
int r = 0;
for (int i = head[x]; ~i && r < f; i = edge[i].next)
if (edge[i].w && dist[edge[i].v] == dist[x] + 1)
{
int delta = dfs(edge[i].v, min(f - r, edge[i].w));
r += delta;
edge[i].w -= delta; edge[i^1].w += delta;
}
if (!r) dist[x] = -1;
return r;
}
int main()
{
memset(head, -1, sizeof(head));
scanf("%d", &N);
for (int i = 1; i <= N; i++)
for (int j = 1, x; j <= N; j++)
{
scanf("%d", &x);
sum += x;
add_edge(S, encode(i, j), x);
add_edge(encode(i, j), i, INF);
add_edge(encode(i, j), j, INF);
}
for (int i = 1, x; i <= N; i++)
scanf("%d", &x), add_edge(i, T, x);
while (bfs())
sum -= dfs(S, INF);
printf("%d\n", sum);
return 0;
}
提交记录(AC / Total = 1 / 2):
Run ID | Remote Run ID | Time(ms) | Memory(kb) | Result | Submit Time |
---|---|---|---|---|---|
8738123 | 1991020 | 8 | 19836 | RE | 2017-04-11 08:55:59 |
8738147 | 1991032 | 1588 | 27556 | AC | 2017-04-11 09:02:30 |