【bzoj1066】: [SCOI2007]蜥蜴

把石柱拆点,流量为高度

然后S与蜥蜴连流量1的边

互相能跳到的石柱连inf的边

石柱能到边界外的和T连inf的边

然后跑dinic就好了

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int N=;
const int inf=1e9;
struct edge{
int next,to,c;
}e[N+];
int ade=,S=,T=,n,m,c,d,CNT=;
int first[N+],dis[N+],now[N+],mp[][],I[][],O[][];
queue <int> Q; void addedge(int x,int y,int cap){
e[++ade].next=first[x];
e[ade].to=y;
e[ade].c=cap;
first[x]=ade;
e[++ade].next=first[y];
e[ade].to=x;
e[ade].c=;
first[y]=ade;
} #define s e[x].to
#define cap e[x].c
#define CAP e[x^1].c
bool bfs(){
for (int i=;i<=CNT;i++) dis[i]=inf;
Q.push(S);
dis[S]=;
while (!Q.empty()){
int p=Q.front();
Q.pop();
for (int x=first[p];x;x=e[x].next){
if (dis[s]>dis[p]+ && cap>){
Q.push(s);
dis[s]=dis[p]+;
}
}
}
return dis[T]!=inf;
} int dfs(int p,int mf){
if (p==T) return mf;
for (int x=now[p];x;x=e[x].next){
now[p]=x;
if (dis[s]==dis[p]+ && cap>){
int f=dfs(s,min(mf,cap));
if (f){
cap-=f;
CAP+=f;
return f;
}
}
}
return ;
}
#undef s
#undef cap
#undef CAP int dinic(){
int ans=,f;
while (bfs()){
for (int i=;i<=CNT;i++) now[i]=first[i];
while (f=dfs(S,inf)){
ans+=f;
}
}
return ans;
} void make_p(){
for (int i=;i<=n;i++){
for (int j=;j<=m;j++){
if (mp[i][j]){
addedge(I[i][j],O[i][j],mp[i][j]);
for (int x=i-d;x<=i+d;x++){
for (int y=j-d;y<=j+d;y++){
if (abs(i-x)+abs(j-y)>d) continue;
if (x< || x>n || y< || y>m) {addedge(O[i][j],T,inf); continue;}
if (mp[x][y] && (x!=i || y!=j)){addedge (O[i][j],I[x][y],inf); }
}
}
}
}
}
} int main(){
scanf("%d%d%d",&n,&m,&d);
for (int i=;i<=n;i++){
char s[];
scanf("%s",s+);
for (int j=;j<=m;j++){
mp[i][j]=s[j]-'';
if (mp[i][j]) I[i][j]=++CNT,O[i][j]=++CNT;
}
}
make_p();
for (int i=;i<=n;i++){
char s[];
scanf("%s",s+);
for (int j=;j<=m;j++){
if (s[j]=='L'){
addedge(S,I[i][j],);
c++;
}
}
}
printf("%d\n",c-dinic());
return ;
}
05-11 16:05