题意:
n*n的图
相邻两##可除去
问最多除去多少
奇偶建图,OK
/* *********************************************** //Author :devil //Created Time :2016/5/12 14:48:15 //************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=605; vector<int>eg[N*N]; char mp[N][N]; int x[N][N],y[N][N],link[N*N]; bool vis[N*N]; bool dfs(int u) { for(int i=0;i<eg[u].size();i++) { int v=eg[u][i]; if(!vis[v]) { vis[v]=1; if(link[v]==-1||dfs(link[v])) { link[v]=u; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); int t,n,cas=0; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); int lx=0,ly=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(mp[i][j]==‘#‘) { if((i+j)%2) x[i][j]=++lx; else y[i][j]=++ly; } } } int m=max(lx,ly); memset(link,-1,sizeof(link)); for(int i=1;i<=m;i++) eg[i].clear(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(mp[i][j]==‘#‘) { if(mp[i+1][j]==‘#‘) { if((i+j)%2) eg[x[i][j]].push_back(y[i+1][j]); else eg[x[i+1][j]].push_back(y[i][j]); } if(mp[i][j+1]==‘#‘) { if((i+j)%2) eg[x[i][j]].push_back(y[i][j+1]); else eg[x[i][j+1]].push_back(y[i][j]); } } } } int ans=0; for(int i=1;i<=lx;i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } printf("Case %d: %d\n",++cas,ans); } return 0; }
时间: 2024-10-05 05:50:02