zoukankan      html  css  js  c++  java
  • BZOJ 4823 [Cqoi2017]老C的方块 ——网络流

    lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html

    我还是太菜了。以后遇到这种题目应该分析分析性质的。

    网络流复杂度真是$O(玄学)$

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define inf 0x3f3f3f3f
    #define ll long long
    #define mp make_pair
    #define maxn 500005
     
    int mov[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    int h[maxn],to[maxn],ne[maxn],fl[maxn],en=0,n,m,k;
    int S=maxn-2,T=maxn-1,dis[maxn];
    queue <int> q;
    map <pair<int,int>,int> Link;
     
    void add(int a,int b,int c)
    {
        to[en]=b;ne[en]=h[a];fl[en]=c;h[a]=en++;
        to[en]=a;ne[en]=h[b];fl[en]=0;h[b]=en++;
    }
     
    bool tell()
    {
        memset(dis,-1,sizeof dis); dis[S]=0; q.push(S);
        while (!q.empty())
        {
            int x=q.front(); q.pop();
            for (int i=h[x];i>=0;i=ne[i])
            if (dis[to[i]]==-1&&fl[i]>0){
                dis[to[i]]=dis[x]+1;
                q.push(to[i]);
            }
        }
        return dis[T]!=-1;
    }
     
    int zeng(int k,int now)
    {
        if (k==T) return now;
        int ret=0;
        for (int i=h[k];i>=0&&ret<now;i=ne[i])
            if (dis[to[i]]==dis[k]+1&&fl[i]>0)
            {
                int tmp=zeng(to[i],min(fl[i],now-ret));
                fl[i]-=tmp;fl[i^1]+=tmp;ret+=tmp;
            }
        if (!ret) dis[k]=-1;
        return ret;
    }
     
    int dinic()
    {
        int ret=0,tmp;
        while (tell()) while (tmp=zeng(S,inf)) ret+=tmp;
        return ret;
    }
     
    int x[maxn],y[maxn],w[maxn];
     
    bool isgreen(int x,int y)
    {
        int tmp=(x>>1)&1;
        if (tmp) return ((x+y)&1);
        else return (!((x+y)&1));
    }
     
    bool isblue(int x,int y)
    {if ((!isgreen(x,y))&&(!((x>>1)&1))) return true;return false;}
     
    bool isred(int x,int y)
    {if ((!isgreen(x,y))&&(!isblue(x,y))) return true;return false;}
     
    bool leftgreen(int x,int y)
    {return (isgreen(x,y))&&(isred(x,y+1))&&(isgreen(x+1,y));}
     
    bool rightgreen(int x,int y)
    {return (isgreen(x,y))&&(isred(x,y+1))&&(isgreen(x-1,y));}
     
    void Finout()
    {
        freopen("block.in","r",stdin);
        freopen("block.out","w",stdout);
    }
     
    int main()
    {
        memset(h,-1,sizeof h);
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        F(i,1,k)
        {
            scanf("%d%d%d",&x[i],&y[i],&w[i]);
            if (isred(x[i],y[i])) add(S,i,w[i]);
            else if (isblue(x[i],y[i])) add(i,T,w[i]);
            Link[mp(x[i],y[i])]=i;
        }
        F(i,1,k)
        {
            if (isblue(x[i],y[i]))
            {
                F(k,0,3)
                {
                    int tx=x[i]+mov[k][0],tmp,ty=y[i]+mov[k][1];
                    if (tx>=1&&tx<=n&&ty>=1&&ty<=m&&isgreen(tx,ty)&&(tmp=Link[mp(tx,ty)]))
                        add(tmp,i,inf);
                }
            }
            else if (isred(x[i],y[i]))
            {
                F(k,0,3)
                {
                    int tx=x[i]+mov[k][0],tmp,ty=y[i]+mov[k][1];
                    if (tx>=1&&tx<=n&&ty>=1&&ty<=m&&isgreen(tx,ty)&&(tmp=Link[mp(tx,ty)]))
                        add(i,tmp,inf);
                }
            }
            else if (leftgreen(x[i],y[i]))
            {
                int tmp;
                if ((tmp=Link[mp(x[i]+1,y[i])]))
                    add(i,Link[mp(x[i]+1,y[i])],min(w[i],w[tmp]));
            }
            else if (rightgreen(x[i],y[i]))
            {
                int tmp;
                if ((tmp=Link[mp(x[i]-1,y[i])]))
                    add(i,Link[mp(x[i]-1,y[i])],min(w[i],w[tmp]));
            }
        }
        printf("%d
    ",dinic());
    }
    

      

  • 相关阅读:
    P2765 魔术球问题 网络流二十四题重温
    搬东西 dp
    Q
    P2774 方格取数问题 网络流重温
    2019牛客暑期多校训练1
    E. A Simple Task
    Codeforces Round #575 (Div. 3) 昨天的div3 补题
    自动化测试如何准备测试数据
    金三银四,资深HR给面试者的十大建议
    我的自动化测试之路[转载]
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6736901.html
Copyright © 2011-2022 走看看