zoukankan      html  css  js  c++  java
  • bzoj 1066: [SCOI2007] 蜥蜴

        这道题还是挺好想的,但我一开始还是想错了……

        把每个石柱拆成两个点,一个入度,一个出度,两个点连一条容量为高度的边,这样就可以限制从此石柱上经过的蜥蜴的数量。关于蜥蜴是否单独成点,我是单独当成了一个点,貌似做麻烦了,可以直接源点连石柱,但那样我想会不会造成一些问题,貌似也没有。

        虽然很水,但还是调了很久。主要问题出在建图上,我把一个点拆成了高度个点,这样无法达到上面说的限制蜥蜴经过的数量这个功能,所以WA了很久,看了题解,才突然明白,这么搞不行……

        代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define N 25
    #define inf 1<<30
    using namespace std;
    
    struct sss
    {
        int x,y;
    }xiyi[N*N];
    int n,m,S,T,d;
    int a[N][N]={0},num[N][N]={0},stonenum=0,xiyinum=0;
    int p[N*N*5],next[N*N*N*N*6],v[N*N*N*N*6],f[N*N*N*N*6],bnum=-1;
    
    bool kexing(int x,int y)
    {
        if (x<1||x>n||y<1||y>m) return false;
        else return true;
    }
    
    void addbian(int x,int y,int flow)
    {
        bnum++; next[bnum]=p[x];
        p[x]=bnum; v[bnum]=y; f[bnum]=flow;
        bnum++; next[bnum]=p[y];
        p[y]=bnum; v[bnum]=x; f[bnum]=0;
    }
    
    int dis[N*N*5];
    
    bool BFS()
    {
        int i,j,k;
        queue<int> q;
        for (i=1;i<=T;i++) dis[i]=-1;
        dis[S]=0; q.push(S);
        while (!q.empty())
        {
            j=q.front(); q.pop(); k=p[j];
            while (k!=-1)
            {
                if (f[k]&&dis[v[k]]==-1)
                {
                    dis[v[k]]=dis[j]+1;
                    q.push(v[k]);
                }
                k=next[k];
            }
        }
        if (dis[T]==-1) return false;
        else return true;
    }
    
    int DFS(int now,int change)
    {
        int i,j,k,flow=0;
        if (now==T||change==0) return change;
        k=p[now];
        while (k!=-1)
        {
            if (f[k]&&dis[v[k]]==dis[now]+1&&(i=DFS(v[k],min(change,f[k])))>0)
            {
                f[k]-=i; f[k^1]+=i;
                flow+=i; change-=i;
                if (change==0) break;
            }
            k=next[k];
        }
        dis[now]=-1;
        return flow;
    }
    
    int dinic()
    {
        int ans=0,flow;
        while (BFS())
            while (flow=DFS(S,inf))
                ans+=flow;
        return ans;
    }
    
    bool bianjie(int x,int y)
    {
        if (x<=d||y<=d) return true;
        else if (n-x<d||m-y<d) return true;
        else return false;
    }
    
    int main()
    {
        int i,j,k,x,y;
        char s[N];
        scanf("%d%d%d",&n,&m,&d);
        S=n*m*3+1; T=n*m*3+2;
        for (i=1;i<=T;i++) p[i]=-1;
        for (i=1;i<=n;i++)
        {
            scanf("%s",s);
            for (j=0;j<m;j++)
                if (s[j]!='0') a[i][j+1]=s[j]-'0';
        }
        for (i=1;i<=n;i++)
        {
            scanf("%s",s);
            for (j=0;j<m;j++)
                if (s[j]=='L')
                {
                    xiyinum++; a[i][j+1]--;
                    xiyi[xiyinum].x=i; xiyi[xiyinum].y=j+1;
                }
        }
        for (i=1;i<=n;i++)
            for (j=1;j<=m;j++)
                if (a[i][j]>0)
                {
                    stonenum++;
                    num[i][j]=stonenum;
                }
        for (i=1;i<=n;i++)
            for (j=1;j<=m;j++)
                if (a[i][j]>0)
                {
                    addbian(num[i][j],num[i][j]+n*m,a[i][j]);
                    if (bianjie(i,j))
                        addbian(num[i][j]+n*m,T,inf);
                    for (int I=-d;I<=d;I++)
                        for (int J=-d;J<=d;J++)
                        if (!(I==0&&J==0)&& I*I+J*J<=d*d)
                        {
                            x=i+I; y=j+J;
                            if (kexing(x,y)&&a[x][y])
                                addbian(num[i][j]+n*m,num[x][y],inf);
                        }
                }
        for (i=1;i<=xiyinum;i++)
        {
            int x1=xiyi[i].x,y1=xiyi[i].y;
            addbian(S,i+n*m*2,1);
            if (bianjie(x1,y1))
                addbian(i+n*m*2,T,inf);
            for (int I=-d;I<=d;I++)
                for (int J=-d;J<=d;J++)
                    if (!(I==0&&J==0)&& I*I+J*J<=d*d)
                    {
                        x=x1+I; y=y1+J;
                        if (kexing(x,y)&&a[x][y])
                            addbian(i+n*m*2,num[x][y],inf);
                    }
        }
        printf("%d
    ",xiyinum-dinic());
    }
  • 相关阅读:
    iOS电商类App研发学习总结
    Swift4.0复习闭包
    Swift4.0复习函数
    Swift4.0复习Optional
    SQL面试题
    sql(join on 和where的执行顺序)
    算法四:回溯和分支界定
    算法三:贪婪算法
    编程之美2.11:寻找最近的点对
    编程之美2.5:寻找最大的K个数
  • 原文地址:https://www.cnblogs.com/handsomeJian/p/3712225.html
Copyright © 2011-2022 走看看