对于该题的建模
考虑类型为二分图,即对N个点进行拆点,左边与行相连,容量为1,右边与列相连,容量为1,然后跑最大流即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 1e6+10;
struct Edge{
int v,next,w;
}edge[N<<1];
int tot=1,head[N],S,T;
const int INF = 1e9;
int d[N],cur[N];
void add(int u,int v,int w1,int w2){
edge[++tot]={v,head[u],w1};
head[u]=tot;
edge[++tot]={u,head[v],w2};
head[v]=tot;
}
bool bfs(){
queue<int>q;
memset(d,0,sizeof d);
d[S]=1;cur[S]=head[S];
q.push(S);
while(q.size()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
int w=edge[i].w;
if(w&&!d[v]){
cur[v]=head[v];
d[v]=d[u]+1;
if(v==T)return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int u,int limit){
if(u==T)return limit;
int flow=0,k;
for(int i=cur[u];i&&flow<limit;i=edge[i].next){
cur[u]=i;
int v=edge[i].v;
int w=edge[i].w;
if(w&&d[v]==d[u]+1){
k=dfs(v,min(w,limit-flow));
if(!k)d[v]=0;
edge[i].w-=k;
edge[i^1].w+=k;
flow+=k;
}
}
return flow;
}
int dinic(){
int maxflow=0,flow;
while(bfs())while(flow=dfs(S,INF))maxflow+=flow;
return maxflow;
}
int id[210][210];
int main(){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
S=2e5;
T=S+1;
for(int i=1;i<=n;i++){
add(S,i,1,0);
}
for(int i=1;i<=m;i++){
add(i+n,T,1,0);
}
for(int i=1;i<=k;i++){
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int u=i+n+m;
int v=i+n+m+2*k;
for(int j=x1;j<=x2;j++){
add(j,u,1,0);
}
add(u,v,1,0);
for(int j=y1;j<=y2;j++){
add(v,j+n,1,0);
}
}
cout<<dinic();
return 0;
}

京公网安备 11010502036488号