明明是经典的行列覆盖模型,居然没想到二分图匹配。
为毛这么弱!!
横竖有相连的就连一条边,最小覆盖点就是最大匹配,总数减去最小覆盖点就是答案。
#include<cstring> #include<iostream> #include<cstdio> using namespace std; struct node1 { int x,y; }heng[1005]; struct node2 { int x,y; }shu[1005]; int g[1005][1005]; int now[1005]; bool vis[1005]; int n,m; bool f(int i,int j) { if(heng[i].x==shu[j].x&&heng[i].y==shu[j].y) return true; if(heng[i].x==shu[j].x&&heng[i].y==shu[j].y+1) return true; if(heng[i].x+1==shu[j].x&&heng[i].y==shu[j].y) return true; if(heng[i].x+1==shu[j].x&&heng[i].y==shu[j].y+1) return true; return false; } int dfs(int k) { for(int i=1;i<=m;i++) { if(!vis[i]&&g[k][i]) { vis[i]=1; if(now[i]==0||dfs(now[i])) { now[i]=k; return 1; } } } return 0; } int main() { while(scanf("%d%d",&n,&m)&&(n||m)) { int ans=0; for(int i=1;i<=n;i++) scanf("%d%d",&heng[i].x,&heng[i].y); for(int i=1;i<=m;i++) scanf("%d%d",&shu[i].x,&shu[i].y); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(f(i,j)) g[i][j]=1; else g[i][j]=0; memset(now,0,sizeof(now)); for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } printf("%d ",m+n-ans); } return 0; }