zoukankan      html  css  js  c++  java
  • Codeforces Gym 100733I The Cool Monkeys 拆点+最大流

    原题链接:http://codeforces.com/gym/100733/problem/I

    题意

    有两颗树(只是树,不是数据结构),每棵树上有不同高度的树枝,然后有m只猴子在某棵树的前m高的树枝上睡觉。早上的时候,他们要到地上,但他们只能从一棵树上跳到另一棵树上,并且跳的高度差也有限制,每个树枝仅能被一只猴子踩过。问你,猴子们是否能够跳到另一棵树最低的m个树枝上。

    题解

    就每个点拆成两个点,然后连边,所有边的容量都为1,然后跑发最大流,考察是否为滿流即可。

    代码

    #include<iostream>
    #include<stack>
    #include<vector>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #define MAX_S (1<<10)+10
    #define MAX_V 2222
    #define MAX_N MAX_V
    #define INF 1000000009
    using namespace std;
    
    struct edge {
        int to, cap, rev;
        bool isRev;
    
        edge(int t, int c, int r, bool i)
                : to(t), cap(c), rev(r), isRev(i) { }
    
        edge() { }
    };
    
    template <class T>
    inline bool scan_d(T &ret)
    {
        char c;
        int sgn;
        if(c=getchar(),c==EOF) return 0; //EOF
        while(c!=' -' &&(c<'0' ||c>'9' )) c=getchar();
        sgn=(c==' -' )?-1:1;
        ret=(c==' -' )?0:(c-'0' );
        while(c=getchar(),c>='0' &&c<='9' ) ret=ret*10+(c-'0' );
        ret*=sgn;
        return 1;
    }
    
    vector<edge> G[MAX_N];
    int level[MAX_V];
    int iter[MAX_V];
    
    void init(int totNode) {
        for (int i = 0; i <= totNode; i++)
            G[i].clear();
        memset(level, 0, sizeof(level));
        memset(iter, 0, sizeof(iter));
    }
    
    void add_edge(int from,int to,int cap) {
        G[from].push_back(edge (to, cap, G[to].size(),0));
        G[to].push_back(edge (from, 0, G[from].size() - 1,1));
    }
    
    void bfs(int s) {
        queue<int> que;
        memset(level, -1, sizeof(level));
        level[s] = 0;
        que.push(s);
        while (!que.empty()) {
            int v = que.front();
            que.pop();
            for (int i = 0; i < G[v].size(); i++) {
                edge &e = G[v][i];
                if (e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }
    }
    
    int dfs(int v,int t,int f) {
        if (v == t)return f;
        for (int &i = iter[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int max_flow(int s,int t) {
        int flow = 0;
        for (; ;) {
            bfs(s);
            if (level[t] < 0)return flow;
            memset(iter, 0, sizeof(iter));
            int f;
            while ((f = dfs(s, t, INF)) > 0) {
                flow += f;
            }
        }
    }
    
    int ha[MAX_N],hb[MAX_N];
    int m,na,nb,t;
    
    int S=2212;
    int T=2211;
    
    bool cmp(int a,int b){
        return a>b;
    }
    
    int main() {
        cin.sync_with_stdio(false);
        cin >> m >> na >> nb >> t;
        for (int i = 0; i < na; i++)cin >> ha[i];
        for (int i = 0; i < nb; i++)cin >> hb[i];
        sort(ha, ha + na,cmp);
        sort(hb, hb + nb,cmp);
        for(int i=0;i<m;i++)
            add_edge(S,i,1);
        for(int i=0;i<na;i++)
            add_edge(i,i+na,1);
        for(int i=1;i<=m;i++)
            add_edge((nb-i)+na+na+nb,T,1);
        for(int i=0;i<nb;i++)
            add_edge(i+na+na,i+na+na+nb,1);
        for(int i=0;i<na;i++)
            for(int j=0;j<nb;j++)
                if(abs(ha[i]-hb[j])<t){
                    add_edge(i+na,j+2*na,1);
                    add_edge(j+2*na+nb,i,1);
                }
        int f=max_flow(S,T);
        if(f>=m){
            cout<<"S"<<endl;
            return 0;
        }
        init(MAX_N);
        for(int i=0;i<m;i++)
            add_edge(S,i+2*na,1);
        for(int i=0;i<na;i++)
            add_edge(i,i+na,1);
        for(int i=1;i<=m;i++)
            add_edge((na-i)+na,T,1);
        for(int i=0;i<nb;i++)
            add_edge(i+na+na,i+na+na+nb,1);
        for(int i=0;i<na;i++)
            for(int j=0;j<nb;j++)
                if(abs(ha[i]-hb[j])<t){
                    add_edge(i+na,j+2*na,1);
                    add_edge(j+2*na+nb,i,1);
                }
        f=max_flow(S,T);
        if (f >= m)
            cout << "S" << endl;
        else
            cout << "N" << endl;
        return 0;
    }
  • 相关阅读:
    Hdu 1257 最少拦截系统
    Hdu 1404 Digital Deletions
    Hdu 1079 Calendar Game
    Hdu 1158 Employment Planning(DP)
    Hdu 1116 Play on Words
    Hdu 1258 Sum It Up
    Hdu 1175 连连看(DFS)
    Hdu 3635 Dragon Balls (并查集)
    Hdu 1829 A Bug's Life
    Hdu 1181 变形课
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4750893.html
Copyright © 2011-2022 走看看