题目大意:给出立方体每个小格堆叠的物体个数,给出三视图,求不改变三视图的情况下能拿走多少物体
题解:减去行列最大值,再通过二分图匹配加上多减的边。
我的收获:enenenen
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAXN 100000+10
typedef long long LL;
struct ed{LL v,next;}edge[MAXN];
LL match[220],head[220],vis[220],n,m;
LL map[220][220],sum=0,mh[220],ml[220];
void add(LL u,LL v){
static LL tot=0;
edge[++tot].v=v;
edge[tot].next=head[u];
head[u]=tot;
}
bool dfs(LL u){
for(LL i=head[u];i;i=edge[i].next){
LL v=edge[i].v;
if(vis[v])continue;
vis[v]=1;
if(!match[v]||dfs(match[v])){
match[v]=u;
return true;
}
}
return false;
}
int main(){
scanf("%lld%lld",&n,&m);
for(LL i=1;i<=n;i++)
for(LL j=1;j<=m;j++){
scanf("%lld",&map[i][j]);
mh[i]=max(mh[i],map[i][j]);
ml[j]=max(ml[j],map[i][j]);
if(map[i][j])sum+=map[i][j]-1;
}
for(LL i=1;i<=n;i++)
for(LL j=1;j<=m;j++)
if(mh[i]&&map[i][j]&&mh[i]==ml[j])add(i,n+j);
for(LL i=1;i<=n;i++)if(mh[i])sum-=mh[i]-1;
for(LL i=1;i<=m;i++)if(ml[i])sum-=ml[i]-1;
for(LL i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
if(mh[i]&&dfs(i))sum+=mh[i]-1;
}
printf("%lld",sum);
return 0;
}