[BZOJ1066][SCOI2007]蜥蜴

来源:互联网 发布:win10工作区的网络 编辑:程序博客网 时间:2024/04/27 23:39

原题地址

网络流.

AC code:

#include <cstdio>#include <algorithm>using namespace std;const int N=1010;const int M=100010;const int INF=1<<28;int  n,m,k,S,T,he,ta,cnt=1,ans;int  head[N],q[N],d[N],cur[N];char map[21][21];struct Edge{    int v,f,next;    Edge() {}    Edge(int v,int f,int next):v(v),f(f),next(next) {}}E[M];int Abs(int x){    return x<0?-x:x;}int numb(int x,int y){    return m*(x-1)+y;}void addedge(int u,int v,int c){    E[++cnt]=Edge(v,c,head[u]);    E[++cnt]=Edge(u,0,head[v]);    head[u]=cnt-1;head[v]=cnt;}void read(){    scanf("%d%d%d",&n,&m,&k);    S=0;T=2*n*m+1;    for(int i=1;i<=n;i++){        scanf("\n");        for(int j=1;j<=m;j++) scanf("%c",&map[i][j]);    }    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(map[i][j]=='0') continue;            addedge(numb(i,j),numb(i,j)+n*m,map[i][j]-'0');            for(int ii=1;ii<=n;ii++){                for(int jj=1;jj<=m;jj++){                    if((i!=ii||j!=jj)&&map[ii][jj]!='0'&&Abs(i-ii)+Abs(j-jj)<=k)                        addedge(numb(i,j)+n*m,numb(ii,jj),INF);                }            }        }    }    for(int i=1;i<=n;i++){        scanf("\n");        for(int j=1;j<=m;j++){            char c;            scanf("%c",&c);            if(c=='.') continue;            addedge(S,numb(i,j),1);            ans++;        }    }    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(map[i][j]=='0'||(min(i,n-i+1)>k&&min(j,m-j+1)>k)) continue;            addedge(numb(i,j)+n*m,T,INF);        }    }}int BFS(){    he=ta=0;q[0]=S;    for(int i=S;i<=T;i++){        d[i]=0;cur[i]=head[i];    }    while(he!=ta+1){        int x=q[he++];        for(int i=head[x];i;i=E[i].next){            Edge e=E[i];            if(e.v==S||d[e.v]||(!e.f)) continue;            d[e.v]=d[x]+1;            q[++ta]=e.v;        }    }    return d[T];}int DFS(int x,int a){    if(x==T||(!a)) return a;    int flow,tag=0;    for(int &i=cur[x];i;i=E[i].next){        Edge e=E[i];        if(d[x]+1!=d[e.v]||(!e.f)) continue;        flow=DFS(e.v,min(e.f,a-tag));        tag+=flow;        E[i].f-=flow;        E[i^1].f+=flow;        if(!(a-tag)) break;    }    return tag;}void Dinic(){    while(BFS()) ans-=DFS(S,INF);}int main(){    read();    Dinic();    printf("%d",ans);    return 0;  }
0 0