• P2472 [SCOI2007]蜥蜴


    https://www.luogu.org/problem/show?pid=2472

    这里写图片描述

    这是一道网络流题,主要是构建图(建模),然后用最大流就可以了;
    虚构一个汇点和一个源点
    构图时,把每个柱子拆成一条边连接两个点,边的容量为柱子高度;
    把可以跳出的柱子连到汇点,容量是INF(不影响结果);
    把源点和有蜥蜴的柱子连一条容量唯一的点,那每只蜥蜴开始跳的时候就相当于从汇点跳来,消耗单位 1 的流量;
    把每条柱子相连,边的容量为INF,构成一个图。
    构图完毕;
    代码;

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #define INF 100000000
    #define po(x) (x)*(x)
    using namespace std;
    char sr,a[21][21];
    int r,c,d,cnt=0,tot=0;
    int map[1500][1500],id[50][50],dep[9999];
    void make1(int x,int y)
    {
        int fto=id[x][y]+1;//此点模拟边的出点 
        for(int i=1;i<=r;i++)
         for(int j=1;j<=c;j++)
        {
            if((i!=x||j!=y)&&a[i][j]>'0')
            {
                if(d*d>=(x-i)*(x-i)+(y-j)*(y-j))  //可以到达的柱子 
                 map[fto][id[i][j]]=INF;
            }
        }
    }
    void make2()
    {
        for(int i=1;i<=r;i++) 
         for(int j=1;j<=c;j++)
        {
            if(a[i][j]>'0')
              if(i+d>r||i-d<1||j+d>c||j-d<1)//可以跳出的柱子         
              {
                  map[id[i][j]+1][cnt]=INF;
              } 
        }
    } 
    int bfs(int s,int t)
    {
        memset(dep,-1,sizeof(dep));
        queue <int> que;
        while(!que.empty()) que.pop();  
        que.push(s);
        dep[s]=0;
        while(!que.empty())
        {
            int k=que.front();
            que.pop();
            for(int i=0;i<=cnt;i++)
              if(map[k][i]>0&&dep[i]==-1)
            {
                dep[i]=dep[k]+1;
                que.push(i);
            }
        }
        return dep[t]!=-1; 
    }
    int dfs(int s,int t,int f)
    {
        if(s==t) return f;
        int b;
        for(int i=0;i<=cnt;i++)
        {
            if(map[s][i]>0&&dep[i]==dep[s]+1&&(b=dfs(i,t,min(f,map[s][i]))))
            {
                map[s][i]-=b;
                map[i][s]+=b;
                return b;
            }
        }
        return 0;
    }
    int Dinic(int s,int t)
    {
        int flow=0;
        while(bfs(s,t))
        {
            while(1)
            {
                int b=dfs(s,t,INF);
                if(b==0) break;
                flow+=b;
            }
        }
        return flow;
    }
    int main()
    {
        //freopen("a.out","w",stdout);
        scanf("%d%d%d
    ",&r,&c,&d);
        for(int i=1;i<=r;i++)
        {
            for(int j=1;j<=c;j++)
            {
                cin>>sr;
                a[i][j]=sr;
                if(sr!='0')
                {
                    cnt++;
                    id[i][j]=cnt;
                    map[cnt][++cnt]=sr-'0';
                }
            }
        }
        for(int i=1;i<=r;i++)
        {
            for(int j=1;j<=c;j++)
            {
                cin>>sr;
                if(sr=='L')
                {
                    tot++;
                    map[0][id[i][j]]=1;
                }
                if(a[i][j]>'0') make1(i,j);
            }
        }
        cnt++;
        make2();
    
        int t=Dinic(0,cnt);
        int ans=tot-t;
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    【2019/7/15】暑假自学——周进度报告
    用户体验评价
    《程序员修炼之道》读后感03
    《程序员修炼之道》读后感02
    《程序员修炼之道》读后感01
    《梦断代码》读后感03——为什么我们不能像造桥一样造软件
    《梦断代码》读后感02——问题的开始
    《梦断代码》读后感01——Chandle的开始
    第二阶段冲刺9
    十五周总结
  • 原文地址:https://www.cnblogs.com/dfsac/p/6819725.html
Copyright © 2020-2023  润新知