您的位置:首页 > 其它

[BZOJ 3996] [TJOI 2015] 线性代数

2015-06-12 11:15 211 查看

3996: [TJOI2015]线性代数

Time Limit: 10 SecMemory Limit: 128 MB

Description

给出一个N*N的矩阵B和一个1*N的矩阵C。求出一个1*N的01矩阵A.使得

D=(A*B-C)*A^T最大。其中A^T为A的转置。输出D

Input

第一行输入一个整数N,接下来N行输入B矩阵,第i行第J个数字代表Bij.
接下来一行输入N个整数,代表矩阵C。矩阵B和矩阵C中每个数字都是不超过1000的非负整数。

Output

输出最大的D

Sample Input

3

1 2 1

3 1 0

1 2 3

2 3 7

Sample Output

2

HINT

1<=N<=500

【题解】

花了好久时间化简,最后化简出来是

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<bitset>
#include<vector>
using namespace std;
#define PA pair<int,int>
const int N=0,M=0;
inline int read()
{int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
return s*f;
}
int n,np,x[505][505],S,T,h[505][505],d[130005];long long ans;
int be[130005],bv[2000005],bl[2000005],bn[2000005],bw=1;
void put(int u,int v,int l)
{++bw;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
void in()
{scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{int s=read();
x[max(i,j)][min(i,j)]+=s;
if(i!=j)ans+=s;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
h[i][j]=++np;
S=++np,T=++np;
for(int i=1;i<=n;i++)
{x[i][i]-=read();
if(x[i][i]>0)ans+=x[i][i];
else put(S,h[i][i],x[i][i]*-1),put(h[i][i],S,0);
}
for(int i=1;i<=n;i++)
{for(int j=1;j<i;j++)
put(h[i][i],h[i][j],min(x[i][i]*-1,x[i][j])),put(h[i][j],h[i][i],0);
for(int j=i+1;j<=n;j++)
put(h[i][i],h[j][i],min(x[i][i]*-1,x[j][i])),put(h[j][i],h[i][i],0);
}
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(x[i][j])
put(h[i][j],T,x[i][j]),put(T,h[i][j],0);
}
int dfs(int x,int sum)
{
if(x==T)return sum;
int ans=0,f=0;
for(int i=be[x];i;i=bn[i])
if(bl[i])
if(d[bv[i]]==d[x]+1)
{f=dfs(bv[i],min(sum,bl[i]));
ans+=f;
sum-=f;
bl[i]-=f;
bl[i^1]+=f;
if(!sum)return ans;
}
return ans;
}
queue<int>q;
int bfs()
{q.push(S);
for(int i=1;i<=np;i++)
d[i]=5000000;
d[S]=1;q.push(S);
while(!q.empty())
{int u=q.front();q.pop();
for(int i=be[u];i;i=bn[i])
if(d[bv[i]]>d[u]+1&&bl[i])
{d[bv[i]]=d[u]+1;
q.push(bv[i]);
}
}
return dfs(S,500000);
}
int main()
{
freopen("algebra.in","r",stdin);
freopen("algebra.out","w",stdout);
in();
int s=0;
while(s=bfs())ans-=s;
printf("%d",ans);
return 0;
}


View Code
这是我在BZOJ AC的第10题,仅此纪念 2015/6/12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: