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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1066

    每个柱子拆成两个点 i<<1,i<<1|1,之间连流量为高度的边

    如果第i根柱子有蜥蜴,S向i<<1连边,流量为1

    如果第i根柱子能跳出去,i<<1|1向T连边,流量为inf

    如果第i根柱子能跳到第j根柱子,i<<1|1向j<<1连边,流量为inf

    至于每根柱子每个时刻只能有一个蜥蜴,不需要管,总可以通过先后顺序调整成满足条件

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 900
    #define M 21500
    
    const int inf=1e9;
    
    char s[21];
    int mp[21][21];
    
    int cnt;
    int id[21][21];
    
    int tot=1;
    int front[N],nxt[M<<1],to[M<<1],val[M<<1],from[M<<1];
    int lev[N],num[N];
    int path[N];
    int cur[N];
     
    int src,decc;
    
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; val[tot]=w;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; val[tot]=0;
        //cout<<u<<' '<<v<<' '<<w<<'
    ';
    }
    
    bool bfs()
    {
        queue<int>q;
        for(int i=src;i<=decc;++i) lev[i]=decc;
        q.push(decc);
        lev[decc]=0;
        int now,t;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            for(int i=front[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==decc && val[i^1]) 
                {
                    lev[t]=lev[now]+1;
                    q.push(t);
                }
            }
        }
        return lev[src]!=decc;
    }
     
    int augment()
    {
        int now=decc,flow=inf;
        int i;
        while(now!=src)
        {
            i=path[now];
            flow=min(flow,val[i]);
            now=from[i];
        }
        now=decc;
        while(now!=src)
        {
            i=path[now];
            val[i]-=flow;
            val[i^1]+=flow;
            now=from[i];
        }
        return flow;
    }
     
    int isap()
    {
        int flow=0;
        if(!bfs()) return 0;
        memset(num,0,sizeof(num));
        for(int i=src;i<=decc;++i) num[lev[i]]++,cur[i]=front[i];
        int now=src,t;
        while(lev[src]<decc)
        {
            if(now==decc)
            {
                flow+=augment();
                now=src;
            }
            bool advanced=false;
            for(int i=cur[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==lev[now]-1 && val[i])
                {
                    advanced=true;
                    path[t]=i;
                    cur[now]=i;
                    now=t;
                    break;
                }
            }
            if(!advanced)
            {
                int mi=decc;
                for(int i=front[now];i;i=nxt[i])
                    if(val[i]) mi=min(mi,lev[to[i]]);
                if(!--num[lev[now]]) break;
                num[lev[now]=mi+1]++;
                cur[now]=front[now];
                if(now!=src) now=from[path[now]];
            }
        }
        return flow;
    }
    
    int main()
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;++i)
        {
            scanf("%s",s+1);
            for(int j=1;j<=m;++j) 
            {
                mp[i][j]=s[j]-'0';
                if(mp[i][j]) id[i][j]=++cnt;
            }
        }
        src=1; decc=(cnt<<1|1)+1;
        int x,y;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                if(!mp[i][j]) continue;
                add(id[i][j]<<1,id[i][j]<<1|1,mp[i][j]);
                for(int r=1;r<=n;++r)
                    for(int c=1;c<=m;++c)
                    {
                        if(!mp[r][c] || (r==i && c==j)) continue;
                        if((r-i)*(r-i)+(c-j)*(c-j)<=k*k) add(id[i][j]<<1|1,id[r][c]<<1,mp[i][j]);
                        //if(abs(r-i)+abs(c-j)<=k) add(id[i][j]<<1|1,id[r][c]<<1,inf);
                    }
                if(i<=k || j<=k || n-i<k || m-j<k) add(id[i][j]<<1|1,decc,inf);
            }
        int sum=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%s",s+1);
            for(int j=1;j<=m;++j)
            {
                if(s[j]=='L') 
                {
                    sum++;
                    add(src,id[i][j]<<1,1);
                }
            }
        }
        cout<<sum-isap();
    }

    1066: [SCOI2007]蜥蜴

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 4407  Solved: 2245
    [Submit][Status][Discuss]

    Description

      在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
    到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
    柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
    变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
    石柱上。

    Input

      输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
    ,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

    Output

      输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

    Sample Input

    5 8 2
    00000000
    02000000
    00321100
    02000000
    00000000
    ........
    ........
    ..LLLL..
    ........
    ........

    Sample Output

    1

    HINT

    100%的数据满足:1<=r, c<=20, 1<=d<=4

  • 相关阅读:
    Kubernetes-Pod的扩、缩容以及滚动升级
    从一个例子开始认识Kubernetes
    Kubernetes的基本术语和概念
    一分钟看懂Docker的网络模式和跨主机通信
    监控神器:Premotheus+Grafana安装
    Linux不同服务器之间copy文件
    Oracle 存储情况查询
    Kubernetes v1.10 快速安装(只需三步)
    django 搭建一个投票类网站(二)
    django 搭建一个投票类网站(一)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8039604.html
Copyright © 2011-2022 走看看