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());
    }
  • 相关阅读:
    组装query,query汇总,query字段
    POJ 1276, Cash Machine
    POJ 1129, Channel Allocation
    POJ 2531, Network Saboteur
    POJ 1837, Balance
    POJ 3278, Catch That Cow
    POJ 2676, Sudoku
    POJ 3126, Prime Path
    POJ 3414, Pots
    POJ 1426, Find The Multiple
  • 原文地址:https://www.cnblogs.com/handsomeJian/p/3712225.html
Copyright © 2011-2022 走看看