列表

详情


NC20452. [TJOI2015]线性代数

描述

给出一个N*N的矩阵B和一个1*N的矩阵C。求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大。其中A^T为A的转置。输出D

输入描述

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

输出描述

输出最大的D

示例1

输入:

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

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 172ms, 内存消耗: 27512K, 提交时间: 2021-02-13 15:26:10

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 300010
#define inf 0x7fffffff
struct node
{
	int y,c,next,ot;
}a[maxn*10];
int len,first[maxn];
int d[maxn],list[maxn*2],head,tail,S,T;
bool vis[maxn];
int mymin(int x,int y)
{
	return (x<y)?x:y;
}
void ins(int x,int y,int c)
{
	len++;
	int now1=len;
	a[len].y=y;
	a[len].c=c;
	a[len].next=first[x];
	first[x]=len;
	len++;
	int now2=len;
	a[len].y=x;
	a[len].c=0;
	a[len].next=first[y];
	first[y]=len;
	a[now1].ot=now2;
	a[now2].ot=now1;
}
bool bfs()
{
	head=1;
	tail=2;
	memset(d,-1,sizeof(d));
	memset(vis,false,sizeof(vis));
	d[S]=1;
	list[head]=S;
	vis[S]=true;
	while(head!=tail)
	{
		int x=list[head];
		for(int k=first[x];k!=-1;k=a[k].next)
		{
			int y=a[k].y;
			if(d[y]==-1&&a[k].c>0)
			{
				d[y]=d[x]+1;
				if(!vis[y])
				{
					list[tail++]=y;
					if(tail>T*2)
					tail=1;
					vis[y]=true;
				}
			 } 
		}
		vis[x]=false;
		head++;
		if(head>T*2)
		head=1;
	}
	return d[T]>0;
}
int dfs(int x,int flow)
{
	if(x==T)
	return flow;
	int minf=0;
	for(int k=first[x];k!=-1;k=a[k].next)
	{
		int y=a[k].y;
		if(d[y]==d[x]+1&&a[k].c>0)
		{
			int p=mymin(flow-minf,a[k].c);
			p=dfs(y,p);
			a[k].c-=p;
			a[a[k].ot].c+=p;
			minf+=p;
			if(minf==flow)
			break;
		}
	}
	if(minf==0)
	d[x]=0;
	return minf;
}
int dinic()
{
	int ret=0;
	while(bfs())
	ret+=dfs(S,inf);
	return ret;
}
int main()
{
	int n,i,j,ls,x,ans=0;
	len=0;
	memset(first,-1,sizeof(first));
	scanf("%d",&n);
	ls=n*n;
	S=n*(n+1)+1;
	T=S+1;
	for(i=1;i<=n;i++)
	for(j=1;j<=n;j++)
	{
		scanf("%d",&x);
		ins(S,(i-1)*n+j,x);
		ins((i-1)*n+j,ls+i,inf);
		ins((i-1)*n+j,ls+j,inf);
		ans+=x;
	}
	for(i=1;i<=n;i++)
	{
		scanf("%d",&x);
		ins(ls+i,T,x);
	}
	printf("%d\n",ans-dinic());
	return 0;
}

上一题