• bzoj1412 [ZJOI2009]狼和羊的故事


    bzoj1412 [ZJOI2009]狼和羊的故事


    网络流最小割题。
    hzwer:挖掘栅栏的本质:只能建在相邻两个,且建好后使得狼和羊之间不存在通路。而割的定义是:使S集和T集不存在通路。而题目又要求建的栅栏最少,于是就是最小割问题了。
    rt,就是裸题。
    这里说1点:我本来想缩点以优化复杂度的,后来发现是错的。。。

    3 3
    1 1 1
    1 0 1
    2 0 2
    

    这组数据,正解3,缩点就变成4了。
    然后。。。
    原因就是:不缩点的话在空格处是限流的,如果缩了点就没有限流了,导致答案过大。
    另外:怎么大家都没加当前弧优化。。。

    
    
    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    char l[110][110];
    const int maxn=10010,maxm=(100*100+100*100+100+100)<<2,S=0,T=10001;
    int dep[maxn],fir[maxn],head[maxn],dis[maxm],w[maxm],nxt[maxm],id=1,n,m;
    il vd _add(int a,int b,int c){nxt[++id]=head[a],head[a]=id,dis[id]=b,w[id]=c;}
    il vd add(int a,int b,int c){_add(a,b,c),_add(b,a,0);}
    il bool BFS(){
        static int que[maxn],hd,tl;static bool vis[maxn];
        memset(vis,0,sizeof vis);hd=tl=0;que[tl++]=S,vis[S]=1,dep[S]=1;
        while(hd^tl){
            static int x;x=que[hd];
            for(int i=head[x];i;i=nxt[i])if(w[i]&&!vis[dis[i]])vis[dis[i]]=1,dep[dis[i]]=dep[x]+1,que[tl++]=dis[i];
            ++hd;
        }return vis[T];
    }
    il int Dinic(int x,int maxflow){
        if(x==T)return maxflow;
        int flow=0,D;
        for(int&i=fir[x];i;i=nxt[i])if(dep[dis[i]]==dep[x]+1&&w[i]){
            D=Dinic(dis[i],min(w[i],maxflow-flow));
            w[i]-=D,w[i^1]+=D,flow+=D;
            if(maxflow==flow)return flow;
        }return flow;
    }
    il int Dinic(){
        int ret=0;
        while(BFS())memcpy(fir,head,sizeof fir),ret+=Dinic(S,23333333);
        return ret;
    }
    #define P(x,y) ((x-1)*m+y)
    il vd Add(int x1,int y1,int x2,int y2){
        char a=l[x1][y1],b=l[x2][y2];
        if(a=='0'&&b=='0')add(P(x1,y1),P(x2,y2),1),add(P(x2,y2),P(x1,y1),1);
        if(a==b)return;
        if((a=='1')||(a=='0'&&b=='2'))add(P(x1,y1),P(x2,y2),1);
        else add(P(x2,y2),P(x1,y1),1);
    }
    int main(){
        n=gi(),m=gi();
        rep(i,1,n)rep(j,1,m)do l[i][j]=getchar();while(l[i][j]>'2'||l[i][j]<'0');
        rep(i,1,n)rep(j,1,m){
            if(l[i][j]=='1')add(S,P(i,j),233333333);
            if(l[i][j]=='2')add(P(i,j),T,233333333);
        }
        rep(i,2,n)Add(i,1,i-1,1);
        rep(i,2,m)Add(1,i,1,i-1);
        rep(i,2,n)rep(j,2,m)Add(i,j,i-1,j),Add(i,j,i,j-1);
        printf("%d",Dinic());
        return 0;
    }
    
  • 相关阅读:
    ubuntu虚拟机下提示Network service discovery disabled
    jq简单实现选项卡--tab
    sublime text 出现错误error trying to parse file:Unexpected trailing characters in PackagesUserDefault(Windows).sublime-keymap:1:54
    sublime text 3设置快捷键让html文件在浏览器打开
    自动刷新浏览器
    项目---开饭了
    关于面试
    软件测试学习-关于三次握手与四次挥手的理解
    软件测试学习-笔记
    软件测试学习-数据库基础
  • 原文地址:https://www.cnblogs.com/xzz_233/p/bzoj1412.html
Copyright © 2020-2023  润新知