zoukankan      html  css  js  c++  java
  • 洛咕 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
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Visual Studio开启SSL的支持
    Linux下ls命令使用详解(转)
    Linux下which命令使用详解(转)
    SQLServer出现不允许保存更改的问题解决
    Mac下包管理平台homebrew的使用
    Jenkins使用FTP进行一键部署及回滚2(Windows)(项目实践)
    TGI
    房地产 专题
    Anaconda
    推荐《用Python进行自然语言处理》中文翻译-NLTK配套书
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9827332.html
Copyright © 2011-2022 走看看