zoukankan      html  css  js  c++  java
  • P2472 [SCOI2007]蜥蜴(最大流)

    P2472 [SCOI2007]蜥蜴

    自己第一道独立做题且一遍AC的网络流题纪念...

    看到这道题我就想到网络流建图的方式了...

    首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离,连边,最后能跳出边界的与t连边,跑最大流即可...

    突然发现最大流与网格图好像有着某种联系...

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=21,INF=1e9;
    int h[N][N],n,m,l,s,t,link[N*N*2],tot=1,d[N*N*2],current[N*N*2],cnt;
    struct edge{int y,v,next;}a[N*N*N*N*2];
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline void add(int x,int y,int v)
    {
        a[++tot].y=y;a[tot].v=v;a[tot].next=link[x];link[x]=tot;
        a[++tot].y=x;a[tot].v=0;a[tot].next=link[y];link[y]=tot;
    }
    inline double dis(int x1,int y1,int x2,int y2)
    {
        double x=x1-x2,y=y1-y2;
        return sqrt(x*x+y*y);
    }
    inline bool bfs()
    {
        queue<int>q;q.push(s);
        memset(d,0,sizeof(d));
        memcpy(current,link,sizeof(current));
        d[s]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=link[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(d[y]||!a[i].v) continue;
                d[y]=d[x]+1;
                q.push(y);
                if(y==t) return true;
            }
        }
        return false;
    }
    inline int dinic(int x,int flow)
    {
        if(x==t) return flow;
        int rest=flow,k;
        for(int i=current[x];i&&rest;i=a[i].next)
        {
            current[x]=i;
            int y=a[i].y;
            if(d[y]==d[x]+1&&a[i].v)
            {
                k=dinic(y,min(rest,a[i].v));
                if(!k) d[y]=0;
                a[i].v-=k;
                a[i^1].v+=k;
                rest-=k;
            }
        }
        return flow-rest;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();m=read();l=read();
        s=0;t=n*m*2+1;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                char c;cin>>c;
                h[i][j]=c-'0';
                add((i-1)*m+j,(i-1)*m+j+n*m,h[i][j]);
            }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                char c;cin>>c;
                if(c=='L') add(s,(i-1)*m+j,1),cnt++;
            }        
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                for(int x=max(1,i-l);x<=min(n,i+l);++x)
                    for(int y=max(1,j-l);y<=min(m,j+l);++y)
                        if(dis(i,j,x,y)<=l) add((i-1)*m+j+n*m,(x-1)*m+y,INF);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                if(i<=l||n-i<l||j<=l||m-j<l) add((i-1)*m+j+n*m,t,INF);
        int maxflow=0,flow;
        while(bfs())
            while(flow=dinic(s,INF)) maxflow+=flow;
        printf("%d",cnt-maxflow);
        return 0; 
    }
    View Code
  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/gcfer/p/12542862.html
Copyright © 2011-2022 走看看