zoukankan      html  css  js  c++  java
  • [BJOI2006][bzoj1001] 狼抓兔子 [最小割]

    题面:

    传送门

    思路:

    其实就是一道最小割的题目......

    我的写法加了两个优化,常数比较小,所以过掉了

    一个是当前弧,一个是若当前点并不能流出去,那么标记dep为-1

    听说正解是对偶图最短路?可以找时间学一学......

    Code:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define inf 1e9
    #define id(i,j) (i-1)*m+j
    using namespace std;
    inline int read(){
        int re=0,flag=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-') flag=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
        return re*flag;
    }
    int n,m,cnt=-1,ans,first[1000010],dep[1000010],cur[1000010];
    int q[1000010],head,tail;
    struct edge{
        int to,next,cap;
    }a[6000010];
    inline void add(int u,int v,int cap){
        a[++cnt]=(edge){v,first[u],cap};first[u]=cnt;
        a[++cnt]=(edge){u,first[v],cap};first[v]=cnt;
    }
    bool bfs(int s,int t){
        int i,u,v;
        head=0,tail=1;q[0]=s;
        for(i=s;i<=t;i++) dep[i]=-1,cur[i]=first[i];
        dep[s]=1;
        while(head<tail){
            u=q[head++];
            for(i=first[u];~i;i=a[i].next){
                v=a[i].to;
                if(~dep[v]||(!a[i].cap)) continue;
                dep[v]=dep[u]+1;
                q[tail++]=v;
            }
        }
        return ~dep[t];
    }
    int dfs(int u,int t,int limit){
        if(u==t||!limit) return limit;
        int i,v,f,flow=0;
        for(i=cur[u];~i;i=a[i].next){
            v=a[i].to;cur[u]=i;//优化一
            if(dep[v]==dep[u]+1&&a[i].cap>0){
                f=dfs(v,t,min(limit,a[i].cap));
                if(f){
                    flow+=f;limit-=f;
                    a[i].cap-=f;a[i^1].cap+=f;
                    if(!limit) return flow;
                }
                else{
                    dep[v]=-1;continue;//优化二
                }
            }
        }
        return flow;
    }
    void dinic(int s,int t){
        int tmp;
        while(bfs(s,t)){
            while(tmp=dfs(s,t,inf)) ans+=tmp;
        }
    }
    int main(){
        memset(first,-1,sizeof(first));
        int i,j,t1;
        n=read();m=read();
        for(i=1;i<=n;i++){
            for(j=1;j<m;j++){
                t1=read();
                add(id(i,j),id(i,j+1),t1);
            }
        }
        for(i=1;i<n;i++){
            for(j=1;j<=m;j++){
                t1=read();
                add(id(i,j),id(i+1,j),t1);
            }
        }
        for(i=1;i<n;i++){
            for(j=1;j<m;j++){
                t1=read();
                add(id(i,j),id(i+1,j+1),t1);
            }
        }
        dinic(1,n*m);
        printf("%d",ans);
    }
  • 相关阅读:
    暑期测试训练3
    对于在线段树上修改整段区间的理解
    UVA 11090 判负圈问题
    ZOJ 2588 求割边问题
    POJ 1523 网络连通
    hdu 1163
    hdu 1703
    hdu 2577 模拟
    hdu 3836 强连通+缩点:加边构强连通
    hdu 2571
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8457378.html
Copyright © 2011-2022 走看看