标签:sgu
题目大意:
给你一个n*m的0,1矩阵(n,m<=200),要你在1的地方放士兵,不能出现
两个士兵相邻,问最多可以放多少个?
解题思路:
首先对根据i+j的奇偶性构建二分图,然后跑一个最大匹配,然后ans=1的个数-最大匹配数应该脑补一下就行了吧。。。。。
然后就是输出的问题了。
首先找到在二分图匹配中没有被匹配到得点,然后将其置为放置士兵,然后在从这个点往周围走,如果周围的点是二分图中匹配的点,我们设这个点为Q,那么我们就递归调用二分图匹配中Q的对应点P,将P点置为放置士兵,如此调用就行了。
AC代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> using namespace std; int n,m; int a[210][210]={{0}}; int hash[210][210]={{0}}; int cz[5][2]={{0,1},{0,-1},{1,0},{-1,0}}; int num=0; int link[210][210][2]={{{0}}}; bool find(int p,int q) { for(int i=0;i<4;i++) { int u=p+cz[i][0],v=q+cz[i][1]; if(u>=1 && u<=n && v>=1 && v<=m && hash[u][v]!=num && a[u][v]) { hash[u][v]=num; if(link[u][v][0]==0 || find(link[u][v][0],link[u][v][1])==true) { link[u][v][0]=p; link[u][v][1]=q; link[p][q][0]=u; link[p][q][1]=v; return true; } } } return false; } void dfs(int p,int q) { hash[p][q]=1; a[p][q]=2; for(int i=0;i<4;i++) { int u=p+cz[i][0],v=q+cz[i][1]; if(u>=1 && u<=n && v>=1 && v<=m && hash[u][v]==0) { hash[u][v]=1; if(link[u][v][0]!=0) dfs(link[u][v][0],link[u][v][1]); } } return; } int main() { int ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); ans+=a[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]!=0 && !((i+j)&1)) { num++; if(find(i,j)==true) ans--; } memset(hash,0,sizeof(hash)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(link[i][j][0]==0 && a[i][j]!=0) dfs(i,j); printf("%d\n",ans); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]==0) printf("#"); else if(a[i][j]==2 || ((!((i+j)&1)) && hash[i][j]==0)) printf("G"); else printf("."); } puts(""); } return 0; }
sgu-234 Black-White King Strikes Back
标签:sgu
原文地址:http://blog.csdn.net/qq_21995319/article/details/44174295