洛咕 P4304 [TJOI2013]攻击装置

把坐标按照(x+y)%2染色可以发现这是个二分图

二分图最大独立集=点数-最大匹配

于是就是个算匹配的傻逼题了

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
char s[210][210];
const int maxn=40010,maxm=2000000;
int num[210][210],cnt,S,T;
int fir[maxn],dis[maxm],nxt[maxm],w[maxm],id=1,head[maxn],dep[maxn];
il vd link(int a,int b){
    nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=1;
    nxt[++id]=fir[b],fir[b]=id,dis[id]=a,w[id]=0;
}
const int dX[]={-1,-2,-1,-2,1,2,1,2},dY[]={2,1,-2,-1,2,1,-2,-1};
il bool BFS(){
    static int que[maxn],hd,tl;
    hd=tl=0;que[tl++]=S;
    memset(dep,0,sizeof dep);dep[S]=1;
    while(hd^tl){
        int x=que[hd++];
        for(int i=fir[x];i;i=nxt[i])
            if(w[i]&&!dep[dis[i]])que[tl++]=dis[i],dep[dis[i]]=dep[x]+1;
    }
    return dep[T];
}
il int Dinic(int x,int maxflow){
    if(x==T)return maxflow;
    int ret=0;
    for(int&i=head[x];i;i=nxt[i])
        if(w[i]&&dep[dis[i]]==dep[x]+1){
            int d=Dinic(dis[i],std::min(w[i],maxflow-ret));
            w[i]-=d,w[i^1]+=d,ret+=d;
            if(ret==maxflow)break;
        }
    return ret;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("4304.in","r",stdin);
    freopen("4303.out","w",stdout);
#endif
    int n=gi();for(int i=1;i<=n;++i)scanf("%s",s[i]+1);
    S=++cnt,T=++cnt;
    int ans=0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){
            if(s[i][j]=='1')continue;
            num[i][j]=++cnt;++ans;
            if((i+j)&1)link(S,num[i][j]);
            else link(num[i][j],T);
        }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            if(s[i][j]=='0'&&((i+j)&1))
                for(int k=0;k<8;++k){
                    int xx=i+dX[k],yy=j+dY[k];
                    if(!num[xx][yy])continue;
                    link(num[i][j],num[xx][yy]);
                }
    while(BFS())memcpy(head,fir,sizeof fir),ans-=Dinic(S,1e9);
    printf("%d\n",ans);
    return 0;
}
posted @ 2018-10-21 22:19  菜狗xzz  阅读(126)  评论(0编辑  收藏  举报