zoukankan      html  css  js  c++  java
  • HDU

    题意:有N*M的矩形,每个格点有一个柱子,每根柱子有高度c,允许蜥蜴经过这根柱子c次,开始有一些蜥蜴在某些柱子上,它们要跳出这个矩形,每步最大能跳d个单位,求最少有多少蜥蜴不能跳出这个矩形。
    分析:转化为求最多有多少蜥蜴能跳出,则变为最大流问题。经典的建图思路,将每个柱子视作点,将其拆为入点和出点,入点到出点建一条容量为c的边,若一个点距离距离边界小于d,建边。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define mp(x,y) make_pair(x,y)
    typedef pair<int,int> PII;
    
    const int INF = 0x3f3f3f3f;
    const int maxn = 1e3+5;
    
    bool vis[maxn];
    struct Edge{
        int from, to,cap,flow;
    };
    int cost[maxn];
    struct Dinic
    {
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
    
        void init(int n){
            this->n = n;
            for(int i=0;i<=n;++i){
                G[i].clear();
            }
            edges.clear();
        }
    
        void AddEdge(int from,int to,int cap){
            edges.push_back((Edge){from,to,cap,0});
            edges.push_back((Edge){to,from,0,0});
            m = edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        bool BFS(){
            memset(vis,0,sizeof(vis));
            queue<int> q;
            q.push(s);
            d[s] = 0;
            vis[s] = 1;
            while(!q.empty()){
                int x = q.front(); q.pop();
                for(int i=0;i<G[x].size();i++){
                    Edge &e = edges[G[x][i]];
                    if(!vis[e.to] && e.flow < e.cap){
                        vis[e.to] = 1;
                        d[e.to] = d[x] + 1;//层次图
                        q.push(e.to);
                    }
                }
            }
            return vis[t];//能否到汇点,不能就结束
        }
        int DFS(int x,int a)//x为当前节点,a为当前最小残量
        {
            if(x == t || a == 0) return a;
            int flow = 0 , r;
            for(int& i = cur[x];i < G[x].size();i++){
                Edge& e = edges[G[x][i]];
                if(d[x] + 1 == d[e.to] && (r = DFS(e.to , min(a,e.cap - e.flow) ) ) > 0 ){
                    e.flow += r;
                    edges[G[x][i] ^ 1].flow -= r;
                    flow += r;//累加流量
                    a -= r;
                    if(a == 0) break;
                }
            }
            return flow;
        }
        int MaxFlow(int s,int t){
            this->s = s; 
            this->t = t;
            int flow = 0;
            while(BFS()){
                memset(cur,0,sizeof(cur));
                flow += DFS(s,INF);
            }
            return flow;
        }
    }F;
    char str[maxn];
    int G[22][22];
    int h,w,d;
    
    bool out(int x,int y)
    {
        if(x<0||x>=h||y<0||y>=w) return true;
        return false;
    }
    
    void build(int x,int y)
    {
        int all = w*h;
        int ed = 2*w*h+1;
        int u = x*w+y;
    
        F.AddEdge(x*w+y,x*w+y+all,G[x][y]);
        
        if(x-d<0 ||x+d>=h||y-d<0 ||y+d>=w){
            F.AddEdge(u+all,ed,INF);
            return;
        }
        for(int i=0;i<h;++i){
            for(int j=0;j<w;++j){
                if(i==x && j==y) continue;
                if(abs(x-i)+abs(y-j)<=d){
                    F.AddEdge(u+all,i*w+j,INF);
                }
            }
        }
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int N,M,T,cas=1; scanf("%d",&T);
        while(T--){
            int u,v,tmp,base;
            int st,ed;
            scanf("%d %d",&h,&d);
            for(int i=0;i<h;++i){
                scanf("%s",str);
                if(i==0){
                    w = strlen(str);
                    base = w*h;
                    st = 2*h*w,ed = st+1;
                    F.init(ed+1);
                }
                for(int j=0;j<w;++j){
                    G[i][j] = (int)(str[j]-'0');
                }
            }
    
            for(int i=0;i<h;++i){
                for(int j=0;j<w;++j){
                    if(!G[i][j]) continue;
                    build(i,j);
                }
            }
    
            int tot = 0;
            for(int i=0;i<h;++i){
                scanf("%s",str);
                for(int j=0;j<w;++j){
                    char c = str[j];
                    if(c=='L'){
                        tot++;
                        u = i*w+j;
                        F.AddEdge(st,u,1);          //源点加边
                    }
                }
            }
            int res= tot - F.MaxFlow(st,ed);
            printf("Case #%d: ",cas++);
            if(!res) printf("no lizard was left behind.
    ");
            else if(res==1) printf("1 lizard was left behind.
    ");
            else printf("%d lizards were left behind.
    ",res);
        }
        return 0;
    }
    
    
    为了更好的明天
  • 相关阅读:
    Python字符串转码问题
    tcpip详解笔记(21) TCP的路径MTU探测与长肥管道
    sync,fsync,fdatasync,fflush
    tcpip详解笔记(22) telnet协议
    tcpip详解笔记(18)TCP的超时与重传
    tcpip详解笔记(16) TCP的交互数据流
    Get exception description and stack trace which caused an exception
    tcpip详解笔记(20) TCP的Keepalive定时器
    [转]应该知道的Linux技巧
    How to prettyprint JSON script?
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9592990.html
Copyright © 2011-2022 走看看