2015
05-23

# Matrix

Let A be a 1*N matrix, and each element of A is either 0 or 1. You are to find such A that maximize D=(A*B-C)*AT, where B is a given N*N matrix whose elements are non-negative, C is a given 1*N matrix whose elements are also non-negative, and AT is the transposition of A (i.e. a N*1 matrix).

The first line contains the number of test cases T, followed by T test cases.
For each case, the first line contains an integer N (1<=N<=1000).
The next N lines, each of which contains N integers, illustrating the matrix B. The jth integer on the ith line is B[i][j].
Then one line followed, containing N integers, describing the matrix C, the ith one for C[i].
You may assume that sum{B[i][j]} < 2^31, and sum{C[i]} < 2^31.

The first line contains the number of test cases T, followed by T test cases.
For each case, the first line contains an integer N (1<=N<=1000).
The next N lines, each of which contains N integers, illustrating the matrix B. The jth integer on the ith line is B[i][j].
Then one line followed, containing N integers, describing the matrix C, the ith one for C[i].
You may assume that sum{B[i][j]} < 2^31, and sum{C[i]} < 2^31.

1
3
1 2 1
3 1 0
1 2 3
2 3 7

2
HintFor sample, A=[1, 1, 0] or A=[1, 1, 1] would get the maximum D. 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXD 1010
#define MAXM 2004010
#include<iostream>
#define INF 0x7fffffff
using namespace std;

int v[MAXM], next[MAXM], flow[MAXM];
int lev[MAXD], q[MAXD], out[MAXD];

void init()
{
e=0;
}

void add(int x, int y, int z)
{
v[e]=y;
flow[e]=z;
v[e]=x;
flow[e]=0;
}

int bfs(int S,int T)
{
int  rear = 0;
memset(lev, -1, sizeof(lev));
lev[S] = 0, q[rear ++] = S;
for(int i = 0; i < rear; i ++)
for(int j = head[q[i]]; j != -1; j = next[j])
if(flow[j] && lev[v[j]] == -1)
{
lev[v[j]] = lev[q[i]] + 1, q[rear ++] = v[j];
if(v[j] == T) return 1;
}
return 0;
}

int dfs(int cur, int a,  int T)
{
if(cur == T)
return a;
for(int &i = out[cur]; i != -1; i = next[i])
if(flow[i] && lev[v[i]] == lev[cur] + 1)
{
int t = dfs(v[i], min(a, flow[i]),T);
if(t)
{
flow[i] -= t, flow[i ^ 1] += t;
return t;
}
}
return 0;
}

long long dinic(int S,int T)
{
long long ans = 0;
while(bfs(S,T))
{
while(int t = dfs(S, INF,T))
ans += t;
}
return ans;
}
int x, a;
int N;
int S = 0, T = N + 1;
long long SUM;
void input()
{
scanf("%d", &N);
init();
S=0;
T=N+1;
SUM = 0;
for(int i = 1; i <= N; i ++)
{
a = 0;
for(int j = 1; j <= N; j ++)
{
scanf("%d", &x), a += x;
}
SUM += a;
}
for(int i = 1; i <= N; i ++)
{
scanf("%d", &x);
}
cout<<SUM-dinic(S,T)<<endl;
}

int main()
{
int t;
scanf("%d", &t);
while(t --)
{
input();
}
return 0;
}


, ,