• bzoj 4200: [Noi2015]小园丁与老司机【dp+有上下界最小流】


    洛谷上有个点死活卡不过去,不知道是哪里写丑了orz
    参考:https://www.cnblogs.com/ditoly/p/BZOJ4200.html
    从上往下dp,设f为不向左右走直接上去的值,g为先向左右走一步再上去,至于找每个方向上的点,分别按x,y,x+y,x-y排序然后二分即可
    然后建出左上右上的图,跑有上下界最小流即可

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int N=50005;
    int n,rl[N],t1[N],t2[N],t3[N],l[N],r[N],f[N],ff[N],lf[N],rf[N],a[N],an,d[N],u[N],c[N],s,t,ans,h[N],cnt=1,le[N];
    vector<int>v,b[N];
    struct qwe
    {
        int ne,to,va;
    }e[N*10];
    struct dian
    {
        int x,y,id;
    }p[N];
    bool cmp1(const dian&a,const dian&b)
    {
        return a.x+a.y==b.x+b.y?a.y<b.y:a.x+a.y<b.x+b.y;
    }
    bool cmp2(const dian&a,const dian&b)
    {
        return a.x-a.y==b.x-b.y?a.y<b.y:a.x-a.y<b.x-b.y;
    }
    bool cmp3(const dian&a,const dian&b)
    {
        return a.x==b.x?a.y<b.y:a.x<b.x;
    }
    bool cmp4(const dian&a,const dian&b)
    {
        return a.y==b.y?a.x<b.x:a.y<b.y;
    }
    int read()
    {
        int r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    void add(int u,int v,int w)
    {
        cnt++;
        e[cnt].ne=h[u];
        e[cnt].to=v;
        e[cnt].va=w;
        h[u]=cnt;
    }
    void ins(int u,int v,int w)
    {
        add(u,v,w);
        add(v,u,0);
    }
    void wk(int u,int v,int l,int r)
    {
        c[u]-=l,c[v]+=l;
        ins(u,v,r-l);
    }
    bool bfs()
    {
        memset(le,0,sizeof(le));
        queue<int>q;
        le[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=h[u];i;i=e[i].ne)
                if(e[i].va>0&&!le[e[i].to])
                {
                    le[e[i].to]=le[u]+1;
                    q.push(e[i].to);
                }
        }
        return le[t];
    }
    int dfs(int u,int f)
    {
        if(u==t||!f)
            return f;
        int us=0;
        for(int i=h[u];i&&us<f;i=e[i].ne)
            if(e[i].va>0&&le[e[i].to]==le[u]+1)
            {
                int t=dfs(e[i].to,min(e[i].va,f-us));
                e[i].va-=t;
                e[i^1].va+=t;
                us+=t;
            }
        if(!us)
            le[u]=0;
        return us;
    }
    int dinic()
    {
        int r=0;
        while(bfs())
            r+=dfs(s,1e9);
        return r;
    }
    void jia(int x,int y)
    {
        if(ff[y]+1>f[x])
            f[x]=ff[y]+1,b[x].clear();
        if(ff[y]+1==f[x])
            b[x].push_back(y);
    }
    void prin(int x)
    {
        a[++an]=x;
        int u=1;
        if(f[x]==ff[x])
        {
            u=0;
            if(p[x].id)
                prin(b[x][0]);
        }
        for(int i=l[x];u&&i<x;i++)
            if(f[i]+x-l[x]==ff[x])
            {
                u=0;
                for(int j=x;--j>i;)
                    a[++an]=j;
                for(int j=l[x];j<=i;j++)
                    a[++an]=j;
                if(p[i].id)
                    prin(b[i][0]);
            }
        for(int i=r[x];u&&i>x;i--)
            if(f[i]+r[x]-x==ff[x])
            {
                u=0;
                for(int j=x;++j<i;)
                    a[++an]=j;
                for(int j=r[x];j>=i;j--)
                    a[++an]=j;
                if(p[i].id)
                    prin(b[i][0]);
            }
    }
    void dfs(int x)
    {
        if(d[x])
            return;
        d[x]=1;
        if(f[x]==ff[x]&&!u[x])
        {
            u[x]=1;
            for(int i=0;i<b[x].size();i++)
                wk(b[x][i],x,1,1e9),dfs(b[x][i]);
        }
        for(int i=l[x];i<x;i++)
            if(f[i]+x-l[x]==ff[x]&&!u[i])
            {
                u[i]=1;
                for(int j=0;j<b[i].size();j++)
                    wk(b[i][j],i,1,1e9),dfs(b[i][j]);
            }
        for(int i=r[x];i>x;i--)
            if(f[i]+r[x]-x==ff[x]&&!u[i])
            {
                u[i]=1;
                for(int j=0;j<b[i].size();j++)
                    wk(b[i][j],i,1,1e9),dfs(b[i][j]);
            }
    }
    int main()
    {
        n=read();
        s=n+3,t=n+4;
        for(int i=1;i<=n;++i)
            p[i].x=read(),p[i].y=read(),p[i].id=i;
        sort(p,p+n+1,cmp1);
        for(int i=0;i<n;i++)
            if(p[i].x+p[i].y==p[i+1].x+p[i+1].y)
                t1[p[i].id]=p[i+1].id;
        sort(p,p+n+1,cmp2);
        for(int i=0;i<n;i++)
            if(p[i].x-p[i].y==p[i+1].x-p[i+1].y)
                t2[p[i].id]=p[i+1].id;
        sort(p,p+n+1,cmp3);
        for(int i=0;i<n;i++)
            if(p[i].x==p[i+1].x)
                t3[p[i].id]=p[i+1].id;
        sort(p,p+n+1,cmp4);
        for(int i=0;i<=n;i++)
            rl[p[i].id]=i;
        memset(f,200,sizeof(f));
        f[rl[0]]=0;
        for(int i=0;i<=n;i=r[i]+1)
        {
            for(l[i]=r[i]=i;r[i]<n&&p[r[i]+1].y==p[r[i]].y;++r[i]);
            for(int j=l[i];++j<=r[i];)
                l[j]=l[i],r[j]=r[i];
            lf[l[i]]=-1e9;
            for(int j=l[i];++j<=r[i];)
                lf[j]=max(lf[j-1],f[j-1]);
            rf[r[i]]=-1e9;
            for(int j=r[i];--j>=l[i];)
                rf[j]=max(rf[j+1],f[j+1]);
            for(int j=l[i];j<=r[i];j++)
            {
                ff[j]=max(f[j],max(lf[j]+j-l[i],rf[j]+r[i]-j));
                if(t1[p[j].id])
                    jia(rl[t1[p[j].id]],j);
                if(t2[p[j].id])
                    jia(rl[t2[p[j].id]],j);
                if(t3[p[j].id])
                    jia(rl[t3[p[j].id]],j);
                if(ff[j]>ans)
                    ans=ff[j],v.clear();
                if(ff[j]==ans)
                    v.push_back(j);
            }
        }
        printf("%d
    ",ans);
        prin(v[0]);
        for(int i=an-1;i>=1;i--)
            printf("%d ",p[a[i]].id);
        puts("");
        for(int i=0;i<v.size();i++)
            dfs(v[i]);
        for(int i=0;i<=n;i++)
            wk(n+1,i,0,1e9),wk(i,n+2,0,1e9);
        for(int i=0;i<=n;i++)
        {
            if(c[i]>0)
                ins(s,i,c[i]);
            else 
                ins(i,t,-c[i]);
        }
        int la0=h[n+1],la1=h[n+2];
        ins(n+2,n+1,1e9);
        dinic();
        int ans=e[cnt].va;//cerr<<ans<<endl;
        h[n+1]=la0,h[n+2]=la1;
        s=n+2,t=n+1;
        printf("%d
    ",ans-dinic());
        return 0;
    }
    
  • 相关阅读:
    10年学到的编程经验总结
    高效阅读源代码指南
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
    如何用git将项目代码上传到github
    关于[].slice.call(arguments, 1) 的思考
    前端笔试题(一)
    2017年第一波JavaScript前端面试题
    2017前端面试题之综合篇(1)
    2017前端面试题之Js篇(1)
    前后端分离后各自职责
  • 原文地址:https://www.cnblogs.com/lokiii/p/10799659.html
Copyright © 2020-2023  润新知