题目大意:给出立方体每个小格堆叠的物体个数,给出三视图,求不改变三视图的情况下能拿走多少物体
题解:减去行列最大值,再通过二分图匹配加上多减的边。
我的收获: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;
}
本文介绍了一种在保持三视图不变的前提下从三维物体中移除最多方块的算法。该算法首先通过减去每行每列的最大高度来计算可移除的方块数量,然后利用二分图匹配的方法来修正因考虑行或列独立而多减去的方块数量。

327

被折叠的 条评论
为什么被折叠?



