传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1976
题解:http://hi.baidu.com/edward_mj/item/13edebea70015f3d86d9dec0
Code:
#include<bits/stdc++.h> using namespace std; const int maxn=40*40*40+10; struct edge{int u,v,cap,flow;}; vector<edge>edges; vector<int>G[maxn]; int s,t; int cur[maxn],d[maxn]; void add(int u,int v,int cap){ // printf("%d->%d cap:%d\n",u,v,cap); edges.push_back((edge){u,v,cap,0}); G[u].push_back(edges.size()-1); edges.push_back((edge){v,u,0,0}); G[v].push_back(edges.size()-1); } bool bfs(){ static int vis[maxn]; memset(vis,0,sizeof vis);vis[s]=1; queue<int>q;q.push(s);d[s]=0; while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<G[u].size();i++){ edge e=edges[G[u][i]];if(vis[e.v]||e.cap==e.flow)continue; d[e.v]=d[u]+1;vis[e.v]=1;q.push(e.v); } }return vis[t]; } int dfs(int u,int a){ if(u==t||!a)return a; int flow=0,f; for(int &i=cur[u];i<G[u].size();i++){ edge e=edges[G[u][i]]; if(d[e.v]==d[u]+1&&(f=dfs(e.v,min(a,e.cap-e.flow)))>0){ edges[G[u][i]].flow+=f; edges[G[u][i]^1].flow-=f; flow+=f;a-=f;if(!a)break; } }return flow; } int dinic(){ int flow=0,x; while(bfs()){ memset(cur,0,sizeof cur); while(x=dfs(s,INT_MAX)){ flow+=x; memset(cur,0,sizeof cur); } }return flow; } int n,tot; int hash[42][42][42],a[42][42][42]; const int dx[6]={0,0,0,0,1,-1}; const int dy[6]={0,0,1,-1,0,0}; const int dz[6]={1,-1,0,0,0,0}; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ char s[42];scanf("%s",s+1); for(int k=1;k<=n;k++)a[i][j][k]=s[k]=='?'?-1:s[k]=='P',hash[i][j][k]=++tot; }s=0;t=tot+1;int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++){ int cnt=0; for(int l=0;l<6;l++){ int x=i+dx[l],y=j+dy[l],z=k+dz[l]; if(x<1||y<1||z<1||x>n||y>n||z>n)continue; cnt++; }sum+=cnt; if((i+j+k)%2){ add(s,hash[i][j][k],cnt); if(a[i][j][k]==1){add(s,hash[i][j][k],INT_MAX);} if(a[i][j][k]==0){add(hash[i][j][k],t,INT_MAX);} for(int l=0;l<6;l++){ int x=i+dx[l],y=j+dy[l],z=k+dz[l]; if(x<1||y<1||z<1||x>n||y>n||z>n)continue; add(hash[i][j][k],hash[x][y][z],2); } }else{ add(hash[i][j][k],t,cnt); if(a[i][j][k]==0){add(s,hash[i][j][k],INT_MAX);} if(a[i][j][k]==1){add(hash[i][j][k],t,INT_MAX);} } } // for(int i=0;i<edges.size();i++)if(i%2==0) // printf("%d->%d cap:%d\n",edges[i].u,edges[i].v,edges[i].cap); cout<<sum-dinic()<<endl; return 0; }