zoukankan      html  css  js  c++  java
  • 蜥蜴(bzoj 1066)

    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

    /*
      挺简单的一道题,搞了将近两个小时,dinic的板子打错了一个地方,找了很长时间。 
      把每个有柱子的点进行拆点,连一条容量为a[i][j]的边,以表示每个点能用的次数,
      源点向每个出发点连一条容量为1的边,每个可到达边界的点向汇点连一条容量为inf的边,
      两个互相可到达的点之间连一条容量为inf的点。 
    */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #define N 1010
    #define M 100010
    #define inf 1000000000
    using namespace std;
    int a[25][25],head[N],dis[N],q[N],r,c,d,n,m,S,T,cnt=1,ans;
    struct node{
        int v,pre,f;
    };node e[M];
    void add(int u,int v,int f){
        e[++cnt].v=v;e[cnt].f=f;e[cnt].pre=head[u];head[u]=cnt;
        e[++cnt].v=u;e[cnt].f=0;e[cnt].pre=head[v];head[v]=cnt;
    }
    double dist(int x1,int y1,int x2,int y2){
        return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    bool bfs(){
        for(int i=1;i<=T;i++)dis[i]=inf;
        int h=0,t=1;q[1]=S;dis[S]=0;
        while(h<t){
            int x=q[++h];
            for(int i=head[x];i;i=e[i].pre){
                int v=e[i].v;
                if(e[i].f&&dis[v]>dis[x]+1){
                    dis[v]=dis[x]+1;
                    if(v==T)return true;
                    q[++t]=v;
                }
            }
        }
        return dis[T]!=inf;
    }
    int dinic(int now,int f){
        if(now==T)return f;
        int rest=f;
        for(int i=head[now];i;i=e[i].pre){
            int v=e[i].v;
            if(dis[v]==dis[now]+1&&e[i].f){
                int t=dinic(v,min(e[i].f,rest));
                if(!t)dis[v]=0;
                e[i].f-=t;
                e[i^1].f+=t;//写成减号了!!!
                rest-=t;
            }
        }
        return f-rest;
    }
    int main(){
        scanf("%d%d%d",&r,&c,&d);
        S=0;T=2*r*c+1;
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++){
                char ch;cin>>ch; 
                a[i][j]=ch-'0';
                if(a[i][j]&&(i-d<=0||i+d>r||j-d<=0||j+d>c))add((i-1)*c+j+T/2,T,inf);
            }
        for(int x1=1;x1<=r;x1++)
            for(int y1=1;y1<=c;y1++){
                if(!a[x1][y1])continue;
                for(int x2=1;x2<=r;x2++)
                    for(int y2=1;y2<=c;y2++){
                        if(x1==x2&&y1==y2)continue;
                        if(dist(x1,y1,x2,y2)<=d)add((x1-1)*c+y1+T/2,(x2-1)*c+y2,inf);
                    }
            }
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++){
                char ch;cin>>ch;
                if(ch=='L')add(S,(i-1)*c+j,1),ans++;
            }
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                if(a[i][j])add((i-1)*c+j,(i-1)*c+j+T/2,a[i][j]);
        while(bfs())ans-=dinic(S,inf);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    学习视频收集
    vscode 编译器插件
    vue2.0父子组件之间传值
    js 案例
    插件
    【转】30分钟掌握 C#6
    【初码干货】关于.NET玩爬虫这些事
    上机作业七 系统进程与计划任务管理
    客户端与服务器双向密钥对验证
    DHCP中继配置
  • 原文地址:https://www.cnblogs.com/harden/p/6260489.html
Copyright © 2011-2022 走看看