链接:https://codeforces.ml/contest/1198/problem/E
题意:给定一个 n × n n\times n n×n 的网格图,给出 m 个矩阵将格子染成黑色。你可以选择任意大小的矩阵 h × w h\times w h×w,并花费 m i n ( h , w ) min(h,w) min(h,w) 将选择的矩阵染回白色。你可以操作任意多次,问将网格图全部染回白色的最小代价
思路:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
namespace Dinic
{
const int MAXN=310,MAXM=2e6+10,inf=1e9+10;
int head[MAXN],cur[MAXN],cnt;
int depth[MAXN];
int maxvex;
struct Edge
{
int nxt,to,flow;
} edges[MAXM<<1];
void init(int n)
{
maxvex=n,cnt=-1;
for(int i=0; i<=n; ++i) head[i]=-1;
}
void add(int u,int v,int flow)
{
edges[++cnt]= {head[u],v,flow};
head[u]=cnt;
edges[++cnt]= {head[v],u,0};
head[v]=cnt;
}
bool bfs(int s,int t)
{
for(int i=0; i<=maxvex; ++i)
cur[i]=head[i],depth[i]=inf;
queue<int> q;
q.push(s);
depth[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u]; i!=-1; i=edges[i].nxt)
{
int v=edges[i].to,flow=edges[i].flow;
if(depth[v]==inf&&flow)
{
depth[v]=depth[u]+1;
q.push(v);
}
}
}
return depth[t]<inf;
}
int dfs(int u,int t,int curflow)//当前边的流
{
if(curflow==0||u==t) return curflow;
int flow=0,f;
for(int i=cur[u]; i!=-1; i=edges[i].nxt)
{
cur[u]=i;//当前弧优化
int v=edges[i].to,eflow=edges[i].flow;
if(depth[v]==depth[u]+1&&(f=dfs(v,t,min(curflow,eflow))))
{
flow+=f;
curflow-=f;
edges[i].flow-=f;
edges[i^1].flow+=f;
if(curflow==0) break;
}
}
return flow;
}
int maxflow(int s,int t)
{
int cnt=0;
int flow=0,f;
while(bfs(s,t))
while((f=dfs(s,t,inf))>0)
flow+=f;
return flow;
}
};
int n,m;
vector<int> allx,ally;
struct Opt
{
int x1,x2,y1,y2;
} opt[60];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; ++i)
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1--,y1--;
opt[i]= {x1,x2,y1,y2};
allx.push_back(x1),allx.push_back(x2);
ally.push_back(y1),ally.push_back(y2);
}
sort(allx.begin(),allx.end());
sort(ally.begin(),ally.end());
allx.resize(unique(allx.begin(),allx.end())-allx.begin());
ally.resize(unique(ally.begin(),ally.end())-ally.begin());
Dinic::init(300);
int s=200,t=201;
for(int i=1; i<allx.size(); ++i)
Dinic::add(s,i,allx[i]-allx[i-1]);
for(int i=1; i<ally.size(); ++i)
Dinic::add(i+100,t,ally[i]-ally[i-1]);
for(int i=1; i<=m; ++i)
{
int x1=lower_bound(allx.begin(),allx.end(),opt[i].x1)-allx.begin()+1;
int x2=lower_bound(allx.begin(),allx.end(),opt[i].x2)-allx.begin()+1;
int y1=lower_bound(ally.begin(),ally.end(),opt[i].y1)-ally.begin()+1;
int y2=lower_bound(ally.begin(),ally.end(),opt[i].y2)-ally.begin()+1;
for(int j=x1; j<x2; ++j)
for(int k=y1; k<y2; ++k)
Dinic::add(j,k+100,1e9+10);
}
int ans=Dinic::maxflow(s,t);
printf("%d\n",ans);
return 0;
}