【题解】Luogu P2472 [SCOI2007]蜥蜴

原题传送门

题目要求无法逃离的最少有多少

直接做肯定不好做,我们帮题目变一个说法:最多能逃离多少

这个询问一看就是最大流

考虑如何建图:

1.将S和每一个有蜥蜴的点连一条流量为1的边(每个蜥蜴只能用1次)

2.每个点拆成两个点(一个点用来连接从其他点连来的边,另一个点用来向其他的点连边,下同),从前一个点向后一个点连一条流量为石柱高度的边(每个石柱只能踩它的高度次)

3.能互相到达的石柱之间连一条流量为inf的边

4.将每一个能跳出地图的点向T连一条流量为inf边

建图后跑一下最大流即可求出答案

#include <bits/stdc++.h>
#define N 1005
#define M 80005
#define inf (1<<30)
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
    return a<b?a:b;
}
inline int Max(register int a,register int b)
{
    return a>b?a:b;
}
struct node{
    int to,next,v;
}e[M];
int head[N],cnt=1;
inline void add(register int u,register int v,register int val)
{
    e[++cnt]=(node){v,head[u],val};
    head[u]=cnt;
}
int n,s,t,maxflow=0,sum=0;
int px[N],py[N],tot=0;
int dep[N],gap[N],cur[N];
inline void bfs()
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    dep[t]=0;
    ++gap[dep[t]];
    queue<int> q;
    q.push(t);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(register int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(dep[v]!=-1)
                continue;
            q.push(v);
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
inline int dfs(register int u,register int flow)
{
    if(u==t)
    {
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for(register int i=cur[u];i;i=e[i].next)
    {
        cur[u]=i;
        int v=e[i].to;
        if(e[i].v&&dep[v]+1==dep[u])
        {
            int tmp=dfs(v,Min(e[i].v,flow-used));
            if(tmp)
            {
                e[i].v-=tmp;
                e[i^1].v+=tmp;
                used+=tmp;
            }
            if(used==flow)
                return used;
        }
    }
    --gap[dep[u]++]==0?dep[s]=n+1:++gap[dep[u]];
    return used;
}
inline void ISAP()
{
    maxflow=0;
    bfs();
    while(dep[s]<n)
    {
        memcpy(cur,head,sizeof(head));
        dfs(s,inf);
    }
}
int main()
{
    int r=read(),c=read(),d=read();
    n=r*c,s=0,t=(n<<1)+1;
    for(register int i=1;i<=r;++i)
        for(register int j=1;j<=c;++j)
        {
            char ch=getchar();
            while(ch!='0'&&ch!='1'&&ch!='2'&&ch!='3')
                ch=getchar();
            ch-=48;
            if(ch)
            {
                add(c*(i-1)+j,c*(i-1)+j+n,ch),add(c*(i-1)+j+n,c*(i-1)+j,0);
                if(i<=d||i+d>r||j<=d||j+d>c)
                    add(c*(i-1)+j+n,t,inf),add(t,c*(i-1)+j+n,0);
                px[++tot]=i,py[tot]=j;
            }
        }
    for(register int i=1;i<=tot;++i)
        for(register int j=i+1;j<=tot;++j)
            if(d*d>=(px[i]-px[j])*(px[i]-px[j])+(py[i]-py[j])*(py[i]-py[j]))
            {
                add(c*(px[i]-1)+py[i]+n,c*(px[j]-1)+py[j],inf),add(c*(px[j]-1)+py[j],c*(px[i]-1)+py[i]+n,0);
                add(c*(px[j]-1)+py[j]+n,c*(px[i]-1)+py[i],inf),add(c*(px[i]-1)+py[i],c*(px[j]-1)+py[j]+n,0);
            }
    for(register int i=1;i<=r;++i)
        for(register int j=1;j<=c;++j)
        {
            char ch=getchar();
            while(ch!='.'&&ch!='L')
                ch=getchar();
            if(ch=='L')
                add(s,c*(i-1)+j,1),add(c*(i-1)+j,s,0),++sum;
        }
    ISAP();
    write(sum-maxflow);
    return 0;
}

原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10316584.html

时间: 2024-07-29 21:06:34

【题解】Luogu P2472 [SCOI2007]蜥蜴的相关文章

P2472 [SCOI2007]蜥蜴(网络流)

P2472 [SCOI2007]蜥蜴 把每个点拆成2个点,两点之间连边的边权为石柱高度 新建虚拟源点$S$和汇点$T$ $S$向所有有蜥蜴的点连边,边权1 其他边都连$inf$ 剩下就是裸的$dinic$辣 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 200005 inline int Min(int

题解 P2472 【[SCOI2007]蜥蜴】

题目链接 Solution [SCOI2007]蜥蜴 题目大意:给定一个\(n\)行\(m\)列的地图,每个点有一个经过次数限制,可以从一个点跳到与它距离不超过\(d\)的另一个点.问有多少只蜥蜴不能从地图中出去 题目分析:有多少只蜥蜴不能从地图中出去,可以转化成最多有多少只蜥蜴可以从地图中出去.然后从一个点跳到另一个点我们自然而然想到连有向边,每个点的经过次数限制可以看做是流量上限.最多有多少只蜥蜴可以出去,就是求最大流量.这不就是一个最大流么.然后我们来看核心--建图 首先,普通的最大流问题

bzoj1066[SCOI2007]蜥蜴

bzoj1066[SCOI2007]蜥蜴 题意: r行c列网格图上有一些高低不平的柱子,一些柱子上有蜥蜴,一只蜥蜴一次能跳距离为d,每次蜥蜴跳跃时出发柱子高度减一,当柱子高度为0时消失,问最少多少蜥蜴不能跳出网格图.r,c≤20,d≤4 题解: 裸最大流,每个柱子拆成X,Y两点,两点之间连柱子的高度,所有Yi向可达柱子的Xi连边,s向所有蜥蜴初始位置连边,所有可以跳出图的柱子向t连边. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #

SCOI2007蜥蜴

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

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴 试题描述 在一个 \(r\) 行 \(c\) 列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为 \(1\),蜥蜴的跳跃距离是 \(d\),即蜥蜴可以跳到平面距离不超过 \(d\) 的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减 \(1\)(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为 \(1\),则蜥蜴离开

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

[bzoj1066]: [SCOI2007]蜥蜴 把石柱拆点,流量为高度 然后S与蜥蜴连流量1的边 互相能跳到的石柱连inf的边 石柱能到边界外的和T连inf的边 然后跑dinic就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <al

【bzoj1066】[SCOI2007]蜥蜴 网络最大流

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

[SCOI2007] 蜥蜴 (最大流)

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

题解 luogu P1850 【换教室】

题解 luogu P1850 [换教室] 时间:2019.8.6 一晚上(约 3.5h 写完) 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 \(2n\) 节课程安排在 \(n\) 个时间段上.在第 \(i\)(\(1 \leq i \leq n\))个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 \(c_i\) 上课,而另一节课程在教室 \(d_i\) 进行. 在不提交任何申请的情况下,学生们需要