• [SCOI2007]蜥蜴


    日常网络流.

    题目大意:

      在一个n*m的矩阵中,每个格子有一定的高度,当高度为0时该格子便不存在,现在这个矩阵中有若干只蜥蜴,每只蜥蜴可以跳到距离不大于d的格子,问有几只蜥蜴无法逃离.

    解题思路:

      一开始看到这道题迷了好久,知道是网络流但是不懂怎么建边,仔细分析了一波题解,发现思路其实很清晰.

      首先,由于格子有权值,于是想到拆点,一只蜥蜴想逃离,路线如下:源点-->柱顶1-->柱底1-->......-->柱顶p-->柱底p-->汇点,这样便可在保证柱子权值的情况下,求出可以逃离的蜥蜴最大数量.

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define R register
    #define next mlgvegetable
    #define debug puts("mlg")
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writesp(ll x);
    inline void writeln(ll x);
    ll n,m,k;
    ll tot=1,head[100100],next[100100],c[100100],to[100100];
    inline void add(ll x,ll y,ll z){
        to[++tot]=y;next[tot]=head[x];head[x]=tot;c[tot]=z;
        to[++tot]=x;next[tot]=head[y];head[y]=tot;c[tot]=0;
    }
    ll d[100010];
    queue<ll>q;
    ll S,T;
    inline bool bfs(){
        while(q.size())q.pop();
        memset(d,0,sizeof d);
        d[S]=1;q.push(S);
        while(q.size()){
            ll x=q.front();q.pop();
            for(R ll i=head[x],ver;i;i=next[i]){
                ver=to[i];
                if(c[i]&&!d[ver]){
                    d[ver]=d[x]+1;
                    q.push(ver);
                    if(ver==T) return true;
                }
            }
        }
        return false;
    }
    inline ll dinic(ll x,ll flow){
        if(x==T||!flow) return flow;
        ll k,rest=flow;
        for(R ll i=head[x],ver;i&&rest;i=next[i]){
            ver=to[i];
            if(d[ver]==d[x]+1&&c[i]){
                k=dinic(ver,min(rest,c[i]));
                if(!k) d[ver]=0;
                c[i]-=k;c[i^1]+=k;rest-=k;
            }
        }
        return flow-rest;
    }
    inline ll calc(ll x,ll y){
        return (x-1)*m+y+n*m;
    }
    inline bool check(ll x,ll y,ll u,ll v){
        return (x-u)*(x-u)+(y-v)*(y-v)<=k*k;
    }
    ll calc1(ll x,ll y){
        return (x-1)*m+y;
    }
    inline ll Read();
    ll mpt[30][30];
    int main(){
        n=read(),m=read(),k=read();
        S=n*m*2+1;T=S+1;
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=m;j++){
                if(mpt[i][j]=Read()){
                    if(i-k<=0||i+k>n||j-k<=0||j+k>m){
                        add(calc(i,j),T,0x7fffffff);    
                    }
                }
            }
        }
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=m;j++){
                if(mpt[i][j]){
                    add(calc1(i,j),calc(i,j),mpt[i][j]);
                    for(R ll u=1;u<=n;u++){
                        for(R ll v=1;v<=m;v++){
                            if((i==u&&j==v)||!mpt[u][v]) continue;
                            if(check(i,j,u,v)) add(calc(i,j),calc1(u,v),0x7fffffff);
                        }
                    }
                }
            }
        }
        ll ans=0;
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=m;j++){
                char c=getchar();while(c!='.'&&c!='L') c=getchar();
                if(c=='L'){
                    add(S,calc1(i,j),1);
                    ans++;
                }
            }
        }
        ll _flow;
        while(bfs()){while(_flow=dinic(S,0x7fffffff)) ans-=_flow;}
        writeln(ans);
    }
    inline ll Read(){
        char ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        return ch-'0';
    }
    inline ll read(){
        ll x=0,t=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-') t=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*t;
    }
    inline void write(ll x){
        if(x<0){putchar('-');x=-x;}
        if(x<=9){putchar(x+'0');return;}
        write(x/10);putchar(x%10+'0');
    }
    inline void writesp(ll x){
        write(x);putchar(' ');
    }
    inline void writeln(ll x){
        write(x);putchar('
    ');
    }

    (代码十分拙劣,懒得改了...)

  • 相关阅读:
    Dart Learn Notes 04
    Dart Learn Notes 03
    Dart Learn Notes 02
    一介书生,仅此而已
    计算机技术的演进及编程语言的多样
    C#方法(用法,参数)
    C#数组--(Array类的属性和方法)
    C#数组--(一维数组,二维数组的声明,使用及遍历)
    程序设计的编程方法
    C#流程控制语句--跳转语句(break,continue,goto,return,)
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13285693.html
Copyright © 2020-2023  润新知