• 【学术篇】网络流24题——方格取数问题


    Emmmm昨天晚上下第二节课回家, 本来觉得自己应该能在1h之内写完调完, 但是网络流板子好像出锅了?
    好像加完当前弧优化就WA掉了? 去掉之后就可以过? 非常不能理解.

    好吧我们来分析题目.

    我们还是按照题目的要求来建图:
    - 不能选有公共边的格子, 我们可以很显然地想到黑白染色, 然后黑点一排, 白点一排.
    - 将源点与每个黑点相连(当然你想连白点也没人管), 流量是这个点的权值.
    - 将每个白点(如果之前连了白点那这次就连黑点咯), 流量是这个点的权值.
    - 将每个黑(白)点与和其有公共边的白(黑)点相连, 流量为.
    - 那么割掉一个点与源点或汇点的连边就表示不选这个点.
    - 所以我们用所有点权的总和减去最小割就ok咯~

    还是画一下样例建图(似乎windows下的画图还是要好用些←_←
    这里写图片描述

    然后就是代码

    #include <queue> 
    #include <cstdio>
    #include <cstring>
    using std::queue;
    const int N=1e4+8;
    const int M=1e5+5;
    const int INF=0x7f7f7f7f;
    inline int gn(int a=0,char c=0){
        for(;c<'0'||c>'9';c=getchar());
        for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
    }
    struct edge{
        int to,next,flow;
    }e[M]; int v[N],tot=1;
    void buildedge(int x,int y,int z){
        e[++tot].to=y; e[tot].next=v[x]; e[tot].flow=z; v[x]=tot;
        e[++tot].to=x; e[tot].next=v[y]; e[tot].flow=0; v[y]=tot;
    }
    int d[N],cur[N],n,m,s,t,sum;
    queue<int> q;
    bool bfs(){
        memset(d,-1,sizeof(d)); d[s]=0; q.push(s);
        while(!q.empty()){
            int x=q.front(); q.pop();
            for(int i=v[x];i;i=e[i].next)
                if(e[i].flow&&d[e[i].to]<0){
                    d[e[i].to]=d[x]+1;
                    q.push(e[i].to);
                }
        }
        return d[t]>0;
    }
    int dfs(int x,int mx,int s=0){ int k;
        if(!mx||x==t) return mx;
        for(int i=v[x];i;i=e[i].next){
            if(d[e[i].to]==d[x]+1){
                k=dfs(e[i].to,std::min(mx,e[i].flow));
                if(k) s+=k,mx-=k,e[i].flow-=k,e[i^1].flow+=k;
                if(!mx) break;
            }
        }
        return s;
    }
    int main(){
        n=gn(); m=gn(); s=0; t=n*m+1;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j){
                int k=(i-1)*m+j,x=gn(); sum+=x;
                if((i+j)&1){
                    buildedge(s,k,x);
                    if(i>1) buildedge(k,k-m,INF);
                    if(i<n) buildedge(k,k+m,INF);
                    if(j>1) buildedge(k,k-1,INF);
                    if(j<m) buildedge(k,k+1,INF);
                }   
                else buildedge(k,t,x);
            }
        while(bfs()) sum-=dfs(s,INF);
        printf("%d",sum);
    }

    反正就这样吧 dinic板子是真的打不对了… 所以到底为什么当前弧优化会被卡啊QAQ

  • 相关阅读:
    About IL, ILGenerator
    何谓系统架构师(转)
    C# weakreference
    新蛋,您能告诉我,这是怎么了吗?
    C#线程同步的常用关键字简介
    [转]百万级访问网站前期的技术准备
    Gridview控件的使用要点
    Asp.net三种页面传值方法
    浅谈 Vue css scoped & module
    Mac iTerm2 zsh: command not found: node/npm/nvm...
  • 原文地址:https://www.cnblogs.com/enzymii/p/8412096.html
Copyright © 2020-2023  润新知