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
  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/zxhl/p/4733726.html
Copyright © 2011-2022 走看看