Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=4619
I learned the magic Hungarian algorithm QwQ tonight
The main idea of the question is to give the coordinates of many 1 * 2 and 2 * 1 blocks, so as to ensure that there is no overlap between 1 * 2 blocks and 2 * 1 blocks, and at most several blocks do not overlap each other.
First, a bipartite graph is established. If two blocks overlap, an edge is drawn between the points they represent. Then the Hungarian algorithm is used to find the maximum matching of bipartite graphs. The answer is the total number of points - the maximum matching number.
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<set> #include<cmath> using namespace std; int used[1005],s[1005],n,m,vis[105][105],line[1005][1005]; bool findd(int x) { for(int i=1;i<=m;i++) { if(line[x][i]&&!used[i]) { used[i]=1; if(s[i]==0||findd(s[i])) { s[i]=x; return 1; } } } return 0; } int main() { while(scanf("%d %d",&n,&m)&&(n||m)) { int hx[1005],hy[1005],sx[1005],sy[1005],ans=0; memset(s,0,sizeof(s)); memset(line,0,sizeof(line)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { scanf("%d %d",&hx[i],&hy[i]); vis[hx[i]][hy[i]]=i; vis[hx[i]+1][hy[i]]=i; } for(int i=1;i<=m;i++) { scanf("%d %d",&sx[i],&sy[i]); if(vis[sx[i]][sy[i]]) { line[vis[sx[i]][sy[i]]][i]=1; } if(vis[sx[i]][sy[i]+1]) { line[vis[sx[i]][sy[i]+1]][i]=1; } } for(int i=1;i<=n;i++) { memset(used,0,sizeof(used)); if(findd(i)) { ans++; } } printf("%d\n",n+m-ans); } }