• codeforces 628F. Bear and Fair Set 网络流


    题目链接

    F. Bear and Fair Set
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Limak is a grizzly bear. He is big and dreadful. You were chilling in the forest when you suddenly met him. It's very unfortunate for you. He will eat all your cookies unless you can demonstrate your mathematical skills. To test you, Limak is going to give you a puzzle to solve.

    It's a well-known fact that Limak, as every bear, owns a set of numbers. You know some information about the set:

    • The elements of the set are distinct positive integers.
    • The number of elements in the set is n. The number n is divisible by 5.
    • All elements are between 1 and b, inclusive: bears don't know numbers greater than b.
    • For each r in {0, 1, 2, 3, 4}, the set contains exactly  elements that give remainder r when divided by 5. (That is, there are elements divisible by 5,  elements of the form 5k + 1,  elements of the form 5k + 2, and so on.)

    Limak smiles mysteriously and gives you q hints about his set. The i-th hint is the following sentence: "If you only look at elements that are between 1 and upToi, inclusive, you will find exactly quantityi such elements in my set."

    In a moment Limak will tell you the actual puzzle, but something doesn't seem right... That smile was very strange. You start to think about a possible reason. Maybe Limak cheated you? Or is he a fair grizzly bear?

    Given nbq and hints, check whether Limak can be fair, i.e. there exists at least one set satisfying the given conditions. If it's possible then print ''fair". Otherwise, print ''unfair".

    Input

    The first line contains three integers nb and q (5 ≤ n ≤ b ≤ 104, 1 ≤ q ≤ 104, n divisible by 5) — the size of the set, the upper limit for numbers in the set and the number of hints.

    The next q lines describe the hints. The i-th of them contains two integers upToi and quantityi (1 ≤ upToi ≤ b0 ≤ quantityi ≤ n).

    Output

    Print ''fair" if there exists at least one set that has all the required properties and matches all the given hints. Otherwise, print ''unfair".

    Examples
    input
    10 20 1
    10 10
    output
    fair
    input
    10 20 3
    15 10
    5 0
    10 5
    output
    fair
    input
    10 20 2
    15 3
    20 10
    output
    unfair
    Note

    In the first example there is only one set satisfying all conditions: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.

    In the second example also there is only one set satisfying all conditions: {6, 7, 8, 9, 10, 11, 12, 13, 14, 15}.

    Easy to see that there is no set satisfying all conditions from the third example. So Limak lied to you :-(

    题目大意: 给你n个数, n是5的倍数,这n个数都不大于b, 并且不相同。 然后刚好有n/5个数%5余0, n/5个数%5余1……。

    然后给你q个限制, 每个限制给出2个数x, y。 说明不大于x的数有y个。 然后问你能否找到一个这样的集合, 满足所给的条件。

    一道网络流的题, 首先如果x1>x2但是y1<y2, 那么肯定不满足。

    源点先向1, 2, 3, 4, 5这5个点连边, 表示余0, 1, 2, 3, 4这五种情况。

    我们根据所给的x, 把[0, b]这个区间划分为q+1个小区间, 然后1, 2, 3, 4, 5这五个点, 分别向这q+1个区间连边,比如说1向某个区间连边, 权值就为这个区间里%5余0的数的个数, 以此类推。

    然后每个区间向汇点连边, 权值为这个区间内的数的个数。

    跑一遍网络流, 看结果是否等于n。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int maxn = 1e6+5;
    int q[maxn*2], head[maxn*2], dis[maxn/10], s, t, num;
    struct node
    {
        int to, nextt, c;
        node(){}
        node(int to, int nextt, int c):to(to), nextt(nextt), c(c){}
    }e[maxn*2];
    void init() {
        num = 0;
        mem1(head);
    }
    void add(int u, int v, int c) {
        e[num] = node(v, head[u], c); head[u] = num++;
        e[num] = node(u, head[v], 0); head[v] = num++;
    }
    int bfs() {
        mem(dis);
        dis[s] = 1;
        int st = 0, ed = 0;
        q[ed++] = s;
        while(st<ed) {
            int u = q[st++];
            for(int i = head[u]; ~i; i = e[i].nextt) {
                int v = e[i].to;
                if(!dis[v]&&e[i].c) {
                    dis[v] = dis[u]+1;
                    if(v == t)
                        return 1;
                    q[ed++] = v;
                }
            }
        }
        return 0;
    }
    int dfs(int u, int limit) {
        if(u == t) {
            return limit;
        }
        int cost = 0;
        for(int i = head[u]; ~i; i = e[i].nextt) {
            int v = e[i].to;
            if(e[i].c&&dis[v] == dis[u]+1) {
                int tmp = dfs(v, min(limit-cost, e[i].c));
                if(tmp>0) {
                    e[i].c -= tmp;
                    e[i^1].c += tmp;
                    cost += tmp;
                    if(cost == limit)
                        break;
                } else {
                    dis[v] = -1;
                }
            }
        }
        return cost;
    }
    int dinic() {
        int ans = 0;
        while(bfs()) {
            ans += dfs(s, inf);
        }
        return ans;
    }
    int a[10005], sum[10005];
    int main()
    {
        int n, b, q, x;
        cin>>n>>b>>q;
        for(int i = 1; i<=q; i++) {
            scanf("%d%d", &a[i], &x);
            sum[a[i]] = x;
        }
        sort(a+1, a+q+1);
        if(a[q]!=n) {
            a[++q] = b;
            sum[b] = n;
        }
        for(int i = 1; i<=q; i++) {
            if(a[i]<sum[a[i]]) {
                puts("unfair");
                return 0;
            }
            if(sum[a[i]]<sum[a[i-1]]) {
                puts("unfair");
                return 0;
            }
        }
        s = 0;
        init();
        for(int i = 1; i<=5; i++) {
            add(s, i, n/5);
        }
        for(int i = 1; i<=5; i++) {
            for(int j = 1; j<=q; j++) {
                int sum1 = a[j]/5+(a[j]%5>=i);
                int sum2 = a[j-1]/5+(a[j-1]%5>=i);
                add(i, 5+j, sum1-sum2);
            }
        }
        t = 5+q+1;
        for(int i = 1; i<=q; i++) {
            add(i+5, t, sum[a[i]]-sum[a[i-1]]);
        }
        int ans = dinic();
        if(ans == n) {
            puts("fair");
        } else {
            puts("unfair");
        }
        return 0;
    }
  • 相关阅读:
    思考
    创建Windows Mobile上兼容性好的UI 程序
    中文乱码(二)
    中文乱码(三)
    MySQL字符集产生乱码的简单讲解
    MySql乱码解决(五)
    中文乱码(四)
    mysql中文问题全处理
    Linux 中 x86 的内联汇编
    arm下的gcc内联汇编
  • 原文地址:https://www.cnblogs.com/yohaha/p/5206784.html
Copyright © 2020-2023  润新知