作为一个富有经营头脑的富翁,小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)
3
3 5 100
0 6 1
6 0 2
1 2 0
# include <iostream>
# include <cstdio>
# include <queue>
# include <cstring>
using namespace std;
typedef long long LL;
const LL inf = 1e16;
const int N = 2e3 + 12;
int head[N],dt,s,t,cur[N],dep[N],n;LL bac;
struct Edge{
int to,nex;LL res;
}edge[N * N];
void AddEdge(int u,int v,LL w)
{
edge[dt] = (Edge){v,head[u],w};
head[u] = dt++;
edge[dt] = (Edge){u,head[v],0};
head[v] = dt++;
}
queue<int> Q;
bool Bfs()
{
for(int i = s;i <= t;i++)dep[i] = -1;
dep[s] = 1;Q.push(s);int u;
while(!Q.empty())
{
u = Q.front();Q.pop();
for(int i = head[u];~i;i = edge[i].nex)if(dep[edge[i].to] == -1 && edge[i].res)
{
dep[edge[i].to] = dep[u] + 1;
Q.push(edge[i].to);
}
}
return dep[t] != -1;
}
LL dfs(int u,LL f)
{
if(u == t || !f)return f;
LL flow = 0,D;
for(int &i = cur[u];~i;i = edge[i].nex)if(dep[edge[i].to] == dep[u] + 1 && (D = dfs(edge[i].to,min(f,edge[i].res))))
{
edge[i].res -= D;edge[i ^ 1].res += D;
f -= D;flow += D;
if(!f)break;
}
return flow;
}
LL Dinic()
{
LL flow = 0;
while(Bfs())
{
for(int i = s;i <= t;i++)cur[i] = head[i];
flow += dfs(s,inf);
}
return flow;
}
int main()
{
memset(head,-1,sizeof head);
scanf("%d",&n);s = 0;t = n + 1;
LL x,ret;
for(int i = 1;i <= n;i++)scanf("%lld",&x),AddEdge(s,i,x);
for(int i = 1;i <= n;i++)
{
ret = 0;
for(int j = 1;j <= n;j++)
{
scanf("%lld",&x);
AddEdge(i,j,x << 1LL);bac += x;
ret += x;
}
AddEdge(i,t,ret);
}
printf("%lld\n",bac - Dinic());
}