赤裸裸的二分匹配。。。
#include"stdio.h" #include"string.h" #define N 601 int map[N][N],v[N],link[N],a[N][N]; char str[N][N]; int n; int dfs(int k) { int i; for(i=0;i<n;i++) { if(map[k][i]&&!v[i]) { v[i]=1; if(link[i]==-1||dfs(link[i])) { link[i]=k; return 1; } } } return 0; } int main() { int i,j,t,ans,tt,cnt; scanf("%d",&t); tt=0; while(t--) { scanf("%d",&n); cnt=0; memset(a,0,sizeof(a)); for(i=0;i<n;i++) { scanf("%s",str[i]); for(j=0;j<n;j++) if(str[i][j]=='#') a[i][j]=cnt++; } memset(map,0,sizeof(map)); for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(str[i][j]=='#') { if(i>0&&str[i-1][j]=='#') map[a[i][j]][a[i-1][j]]=1; if(i<n-1&&str[i+1][j]=='#') map[a[i][j]][a[i+1][j]]=1; if(j>0&&str[i][j-1]=='#') map[a[i][j]][a[i][j-1]]=1; if(j<n-1&&str[i][j+1]=='#') map[a[i][j]][a[i][j+1]]=1; } } } n=cnt; memset(link,-1,sizeof(link)); ans=0; for(i=0;i<n;i++) { memset(v,0,sizeof(v)); if(dfs(i)) ans++; } printf("Case %d: %d\n",++tt,ans/2); } return 0; }