標籤:blog os io 資料 for ar 2014 amp
要用1×2的板子盡量多的覆蓋##地區,且不能交叉,求至多可以覆蓋多少板子。
每一個#向向下或向右相鄰的#建邊。求最大匹配就可以了。
其實這題資料是比較弱的把,應該是#的個數在600以內把。。
#include <iostream>#include <cstdlib>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#define inf 0x3f3f3f3f#pragma comment(linker, "/STACK:16777216")#define eps 1e-6#define ll long longusing namespace std;int n,cnt,mx[605],my[605],vis[605],e[605][605],mp[605][605];char s[605][605];int path(int i){ int j; for(j=1;j<cnt;j++) { if(e[i][j]&&!vis[j]) { vis[j]=1; if(my[j]==-1||path(my[j])) { my[j]=i; mx[i]=j; return 1; } } } return 0;}int hungary(){ int res=0; memset(mx,-1,sizeof mx); memset(my,-1,sizeof my); for(int i=1;i<cnt;i++) { if(mx[i]==-1) { memset(vis,0,sizeof vis); res+=path(i); } } return res;}int main(){ int icy,cas=1,i,j; scanf("%d",&icy); while(icy--) { scanf("%d",&n); memset(e,0,sizeof e); memset(mp,0,sizeof mp); for(i=0;i<n;i++) scanf("%s",s[i]); cnt=1; for(i=0;i<n;i++) for(j=0;j<n;j++) if(s[i][j]=='#') mp[i][j]=cnt++; for(i=0;i<n;i++) for(j=0;j<n;j++) { if(mp[i][j]) { if(i<n-1&&mp[i+1][j]) e[mp[i][j]][mp[i+1][j]]=e[mp[i+1][j]][mp[i][j]]=1; if(j<n-1&&mp[i][j+1]) e[mp[i][j+1]][mp[i][j]]=e[mp[i][j]][mp[i][j+1]]=1; } } memset(vis,0,sizeof vis); int ans=hungary(); printf("Case %d: %d\n",cas++,ans/2); } return 0;}