zoukankan      html  css  js  c++  java
  • 【bzoj1066】[SCOI2007]蜥蜴 网络最大流

    【bzoj1066】[SCOI2007]蜥蜴

    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<=3

    代码

    对于每根石柱,采取一分为二的想法,即把一个点分为两个点(可抽象为石柱底部到顶部),其连线容量限制为石柱高度。

    超级源与所有有蜥蜴的点相连,容量为1。

    超级汇与地图内所有能跳出的点的底端相连,容量为INF。

    对于地图内任意两个石柱,如果间距小于d,就将其中一根石柱的底部与另一根石柱的顶部相连,其连线容量为INF。

    构图完成,剩下就是跑一遍最大流,然后用蜥蜴数量减去最大流就是最终结果。

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <queue>
    #include <typeinfo>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //***************************
    namespace NetFlow
    {
    const int MAXN=100000,MAXM=500000,inf=1e9;
    struct Edge
    {
        int v,c,f,nx;
        Edge() {}
        Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
    } E[MAXM];
    int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
    void init(int _n)
    {
        N=_n,sz=0;
        memset(G,-1,sizeof(G[0])*N);
    }
    void link(int u,int v,int c)
    {
        E[sz]=Edge(v,c,0,G[u]);
        G[u]=sz++;
        E[sz]=Edge(u,0,0,G[v]);
        G[v]=sz++;
    }
    int ISAP(int S,int T)
    {
        //S -> T
        int maxflow=0,aug=inf,flag=false,u,v;
        for (int i=0; i<N; ++i)cur[i]=G[i],gap[i]=dis[i]=0;
        for (gap[S]=N,u=pre[S]=S; dis[S]<N; flag=false)
        {
            for (int &it=cur[u]; ~it; it=E[it].nx)
            {
                if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+1)
                {
                    if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f;
                    pre[v]=u,u=v;
                    flag=true;
                    if (u==T)
                    {
                        for (maxflow+=aug; u!=S;)
                        {
                            E[cur[u=pre[u]]].f+=aug;
                            E[cur[u]^1].f-=aug;
                        }
                        aug=inf;
                    }
                    break;
                }
            }
            if (flag) continue;
            int mx=N;
            for (int it=G[u]; ~it; it=E[it].nx)
            {
                if (E[it].c>E[it].f&&dis[E[it].v]<mx)
                {
                    mx=dis[E[it].v];
                    cur[u]=it;
                }
            }
            if ((--gap[dis[u]])==0) break;
            ++gap[dis[u]=mx+1];
            u=pre[u];
        }
        return maxflow;
    }
    bool bfs(int S,int T)
    {
        static int Q[MAXN];
        memset(dis,-1,sizeof(dis[0])*N);
        dis[S]=0;
        Q[0]=S;
        for (int h=0,t=1,u,v,it; h<t; ++h)
        {
            for (u=Q[h],it=G[u]; ~it; it=E[it].nx)
            {
                if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                {
                    dis[v]=dis[u]+1;
                    Q[t++]=v;
                }
            }
        }
        return dis[T]!=-1;
    }
    int dfs(int u,int T,int low)
    {
        if (u==T) return low;
        int ret=0,tmp,v;
        for (int &it=cur[u]; ~it&&ret<low; it=E[it].nx)
        {
            if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
            {
                if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                {
                    ret+=tmp;
                    E[it].f+=tmp;
                    E[it^1].f-=tmp;
                }
            }
        }
        if (!ret) dis[u]=-1;
        return ret;
    }
    int dinic(int S,int T)
    {
        int maxflow=0,tmp;
        while (bfs(S,T))
        {
            memcpy(cur,G,sizeof(G[0])*N);
            while (tmp=dfs(S,T,inf)) maxflow+=tmp;
        }
        return maxflow;
    }
    }
    using namespace NetFlow;
    double dist(int a,int b,int x,int y)
    {
        return sqrt((b-y)*(b-y)+(a-x)*(a-x));
    }
    int  main()
    {
        int n,m,d;
        char mp[33][33],mp2[33][33];
        cin>>n>>m>>d;
        init(1500);
        for(int i=1; i<=n; i++)
        {
            scanf("%s",mp[i]+1);
        }
        for(int i=1; i<=n; i++)
        {
            scanf("%s",mp2[i]+1);
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if((mp[i][j]-'0')>0)
                {
                    for(int h=i-d; h<=i+d; h++)
                    {
                        for(int k=j-d; k<=j+d; k++)
                        {
                            if(h==i&&j==k)continue;
                            if(h<0||k<0||h>n+1||k>m+1)
                                continue;
                            double dd=d*1.0;
                            if(dist(i,j,h,k)>dd)continue;
                            if(h==0||k==0||h==n+1||k==m+1)
                                link((i-1)*m+j+400,1000,inf);
                            else  link((i-1)*m+j+400,(h-1)*m+k,inf);
                        }
                    }
                    link((i-1)*m+j,(i-1)*m+j+400,mp[i][j]-'0');
                }
    
            }
        }
        int sum=0;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(mp2[i][j]=='L')
                {
                    sum++;
                    link(999,(i-1)*m+j,1);
                }
            }
        }
        cout<<sum-dinic(999,1000)<<endl;
        return 0;
    }

    补:

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 1e3+500, M = 1e3+20, mod = 1e9+7, inf = 2e9;
    
    char s[30];
    int head[N],S,T,r,c,d,t=2,h[N],height[30][30],q[N],ans;
    struct edge{int to,next,v;}e[N*N];
    void adds(int u,int v,int w) {e[t].next=head[u];e[t].to=v;e[t].v=w;head[u]=t++;}
    void add(int u,int v,int w) {adds(u,v,w);adds(v,u,0);}
    
    bool bfs() {
        memset(h,-1,sizeof(h));
        int l = 0, r = 1,now;
        q[l] = S;
        h[S] = 0;
        while(l!=r) {
            now=q[l++];if(l == 900) l=0;
            for(int i=head[now];i;i=e[i].next) {
                if(e[i].v&&h[e[i].to]==-1) {
                    h[e[i].to] = h[now] + 1;
                    q[r++]=e[i].to;
                    if(r == 900) r = 0;
                }
            }
        }
        if(h[T] == -1) return 0;
        return 1;
    }
    int dfs(int x,int f) {
        if(x == T) return f;
        int used=0,w;
        for(int i=head[x];i;i=e[i].next) {
            if(e[i].v&&h[e[i].to] == h[x]+1) {
                w = dfs(e[i].to,min(f-used,e[i].v));
                used+=w;e[i].v-=w;e[i^1].v+=w;
                if(used == f) return f;
            }
        }
        return used;
    }
    void dinic() {while(bfs()) ans+=dfs(S,inf);}
    
    double dis(int i,int j,int k,int h) {return sqrt(1.0*(i-k)*(i-k) + 1.0*(j-h)*(j-h));}
    int main() {
        scanf("%d%d%d",&r,&c,&d);
        S=3*r*c,T=S+1;
        for(int i = 1; i <= r; ++i)
        {
            scanf("%s",s+1);
            for(int j = 1; j <= c; ++j)
            {
                height[i][j] = s[j]-'0';
                add((i-1)*c+j,(i-1)*c+j+r*c,height[i][j]);
                if(i-d<=0||j-d<=0||i+d>r||j+d>c)
                {
                    add((i-1)*c+j+r*c,T,inf);
                }
            }
        }
        int sum = 0;
        for(int i = 1; i <= r; ++i)
        {
            scanf("%s",s+1);
            for(int j = 1; j <= c; ++j) {
                if(s[j] == 'L')
                {
                    sum++;
                    add(S,(i-1)*c+j,1);
                }
                for(int k = 1; k <= r; ++k)
                for(int h = 1; h <= c; ++h) {
                    if((k!=i||j!=h) && dis(i,j,k,h) <= 1.0*d)
                    {
                        add((i-1)*c+j+r*c,(k-1)*c+h,inf);
                    }
                }
            }
        }
        dinic();
        printf("%d
    ",sum-ans);
        //cout<<sum-ans<<endl;
        return 0;
    }
    dinic
  • 相关阅读:
    LeetCode "Minimum Moves to Equal Array Elements"
    LeetCode "Third Maximum Number"
    LeetCode "Arranging Coins"
    LeetCode "Is Subsequence"
    HackerRank "Flatland Space Stations"
    LeetCode "Super Pow"
    LeetCode "Wiggle Subsequence" !
    HackerRank "Jumping on the Clouds"
    HackerRank "Fair Rations"
    HackerRank "Equal Stacks"
  • 原文地址:https://www.cnblogs.com/zxhl/p/4733726.html
Copyright © 2011-2022 走看看