• bzoj 1066: [SCOI2007]蜥蜴


    题目链接

    bzoj 1066: [SCOI2007]蜥蜴

    题解

    对于每块石头拆点限流为高度
    限制跳跃次数
    对于能跳出去的石头的连接汇点容量为INF
    源点连接青蛙容量为1
    对于互相能到达的点建立容量为INF的边
    求出最大流为做多逃出数
    答案为青蛙数-最大流

    代码

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #define INF 0x7fffffff
    using std::queue;
    const int maxn=1010;
    struct node {
        int v,next,flow;
    }edge[maxn*50];int num=1;
    int r,c,d,S,T,cur[maxn],head[maxn],lev[maxn];
    char s[31];
    int mp[31][31];
    void add_edge(int u,int v,int flow) {
        edge[++num].v=v;edge[num].flow=flow;edge[num].next=head[u];head[u]=num;
        edge[++num].v=u;edge[num].flow=0;edge[num].next=head[v];head[v]=num;
    }
    double calc_dis(int x1,int y1,int x2,int y2) {return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
    int calc_pos(int x,int y,int add) {return (x-1)*c+y+r*c*add;}
    bool judge(int x,int y) {return x<=d||r-x<d||y<=d||c-y<d;}
    bool spfa() {
        memset(lev,-1,sizeof lev);
        memcpy(cur,head,sizeof head);
        queue<int>que;
        que.push(S);lev[S]=0;
        while(!que.empty()) {
            int u=que.front();que.pop();
            for(int i=head[u];i;i=edge[i].next) {
                int v=edge[i].v;
                if(edge[i].flow>0&&lev[v]<0) {
                    lev[v]=lev[u]+1;que.push(v);
                }
            }
        }
        if(lev[T]!=-1)return true;
        else return false;
    }   
    int dfs(int now,int flow) {
        if(now==T)return flow;
        int rest=0,delta;
        for(int &i=cur[now];i;i=edge[i].next) {
            int v=edge[i].v;
            if(lev[v]==lev[now]+1&&edge[i].flow>0) {
                delta=dfs(v,std::min(flow-rest,edge[i].flow));
                if(delta) {
                    edge[i].flow-=delta;
                    edge[i^1].flow+=delta;
                    rest+=delta;if(rest==flow)break;
                }
            }
        }
        if(rest==flow)lev[now]=-1;
        return rest;
    }
    int dinic() {
        int ret=0;
        while(spfa())
            ret+=dfs(S,INF);
        return ret;
    }
    int main(){
        int cnt=0;
        scanf("%d%d%d",&r,&c,&d); T=2*r*c+1;
        for(int i=1;i<=r;i++){
            scanf("%s",s+1);
            for(int j=1;j<=c;j++) mp[i][j]=s[j]-'0';
        }
        for(int i=1;i<=r;i++) {
            scanf("%s",s+1);
            for(int j=1;j<=c;j++) {
                if(s[j]=='L') cnt++,add_edge(S,calc_pos(i,j,0),1);
            }
        }
        for(int i=1;i<=r;i++) 
            for(int j=1;j<=c;j++) 
                if(mp[i][j]) add_edge(calc_pos(i,j,0),calc_pos(i,j,1),mp[i][j]);
        for(int x1=1;x1<=r;x1++) 
            for(int y1=1;y1<=c;y1++) {
                if(!mp[x1][y1]) continue;
                for(int x2=1;x2<=r;x2++) 
                    for(int y2=1;y2<=c;y2++) {
                        if(x1==x2&&y1==y2) continue;
                        if(mp[x2][y2]&&calc_dis(x1,y1,x2,y2)<=d) {
                            add_edge(calc_pos(x1,y1,1),calc_pos(x2,y2,0),INF);
                            add_edge(calc_pos(x2,y2,1),calc_pos(x1,y1,0),INF);
                        }
                    }
        	}
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                if(judge(i,j)) add_edge(calc_pos(i,j,1),T,INF);
        printf("%d",cnt-dinic());
        return 0;
    }
    
  • 相关阅读:
    Docker跨平台架构的新特性buildx的启用方式
    Linux 如何安装rvm和ruby
    Linux
    ubuntu安装 vmware workstation pro 15.1.1
    docker-compose搭建golang本地开发环境
    linux 常用命令
    leetcode 1046 最后一块石头的重量
    leetcode 330 按要求补齐数组
    MySQL 字符集与比较规则
    Python 是什么语言
  • 原文地址:https://www.cnblogs.com/sssy/p/8439799.html
Copyright © 2020-2023  润新知