zoukankan      html  css  js  c++  java
  • 2020 Multi-University Training Contest 4 1007 Go Running(网络流)

    题目

      http://acm.hdu.edu.cn/showproblem.php?pid=6808

    题意

      在一个二维空间中,有一种检测机器,可以告诉你在 t 时刻 x 位置有人跑步经过。已知人跑步速度为 1 m/s,现给出 n 个机器的检测数据,问最少有多少人在跑步。

    题解

      由每个机器数据可知若要在 t 时刻 x 位置能检测到,那么只有在 0 时刻 x - t 位置向正方向移动 和 x + t 位置向负方向移动两种情况,当我们将 x 和 t 作为坐标画到坐标轴上时,如下图所示。由于速度为 1 m/s,所以能够很快发现被斜率为 1 或 -1 的直线同时穿过的点能够只用一个人就够了。所以本题就变成了用最少数量的斜率为 1 或 -1 的直线覆盖所有的点,那么我们这时候将 x - t(斜率为1)和 x + t(斜率为-1) 作为二分图两边的匹配点,由 x - t 的点向 x + t 的点引出一条边,题目就变为了求二分图的最小点覆盖为题,而最小点覆盖就等于最大匹配数,也就是最大网络流问题。

    #include <bits/stdc++.h>
    // #include <iostream>
    // #include <cstring>
    // #include <string>
    // #include <algorithm>
    // #include <cmath>
    // #include <cstdio>
    // #include <queue>
    // #include <stack>
    // #include <map>
    // #include <bitset>
    // #include <set>
    // #include <vector>
    // #include <iomanip>
    #define ll long long
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    #define bep(i, a, b) for(int i = a; i >= b; --i)
    #define lowbit(x) (x&(-x))
    #define MID (l + r) / 2
    #define ls pos*2
    #define rs pos*2+1
    #define pb push_back
    #define ios() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
    
    using namespace std;
    
    const int maxn = 1e6 + 1010;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll mod = 1e9 + 7;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    struct node {
        ll x, t;
    }arr[maxn];
    struct Edge {
        int to;
        int flow;
        int net;
    }edge[maxn*2];
    
    int head[maxn*2], cnt;
    int cpy[maxn];
    int lv[maxn];
    ll b[maxn], tail;
    queue<int> que;
    
    void addedge(int u, int v, int flow) {
        edge[cnt] = (Edge){v, flow, head[u]};
        head[u] = cnt++;
        edge[cnt] = (Edge){u, 0, head[v]};
        head[v] = cnt++;
    }
    int bfs(int s, int e) {
        rep(i, 0, 2*tail + 1) lv[i] = 0;
        while(!que.empty()) que.pop();
        que.push(s);
        lv[s] = 1;
        while(!que.empty()) {
            int t = que.front();
            que.pop();
            for(int i = head[t]; i != -1; i = edge[i].net) {
                int to = edge[i].to;
                if(!lv[to] && edge[i].flow) {
                    lv[to] = lv[t] + 1;
                    que.push(to);
                }
            }
            if(lv[e]) return 1;
        }
        return 0;
    }
    int dfs(int s, int e, int limit) {
        if(s == e || !limit) return limit;
        int flow = 0;
        int minn;
        for(int &i = head[s]; i != -1; i = edge[i].net) { 
            int to = edge[i].to;
            if(lv[to] == lv[s] + 1 && (minn = dfs(to, e, min(limit, edge[i].flow)))) {
                flow += minn;
                edge[i].flow -= minn;
                edge[i^1].flow += minn;
                limit -= minn;
                if(!limit) break;
            }
        }
        return flow;
    }
    int dinic(int s, int e) {
        int maxflow = 0;
        memcpy(cpy, head, sizeof(int) * (2*tail + 1));
        while(bfs(s, e)) {
            maxflow += dfs(s, e, inf);
            memcpy(head, cpy, sizeof(int) * (2*tail + 1));
        }
        return maxflow;
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            tail = 0;
            int n;
            scanf("%d", &n);
            rep(i, 1, n) {
                cin >> arr[i].x >> arr[i].t;
                b[++tail] = arr[i].x - arr[i].t;
                b[++tail] = arr[i].x + arr[i].t;
            }
            sort(b + 1, b + 1 + tail);
            tail = unique(b + 1, b + 1 + tail) - b - 1;
            cnt = 0;
            rep(i, 0, 2*tail + 1) head[i] = -1;
            rep(i, 1, tail) {
                addedge(0, i, 1);
                addedge(i + tail, 2*tail + 1, 1);
            }
            rep(i, 1, n) {
                int u = lower_bound(b + 1, b + 1 + tail, arr[i].x - arr[i].t) - b;
                int v = lower_bound(b + 1, b + 1 + tail, arr[i].x + arr[i].t) - b + tail;
                // cout << u << ' ' << v << "---" << endl;
                addedge(u, v, 1);
            }
            cout << dinic(0, 2*tail + 1) << endl;
        }
        return 0;
    }
  • 相关阅读:
    第十一节 1虚拟路径 简单
    第十一节 4Server对象 简单
    第十节 19验证码案例 简单
    第十节 19爆力注册 简单
    第十节 23行删除例子讲解请求处理响应 简单
    第十节 18暴力破解及机器人注册原理 简单
    第十一节 2Request对象 简单
    礼物
    笔记本电脑与漂亮老婆
    一场傻B的晚会
  • 原文地址:https://www.cnblogs.com/Ruby-Z/p/13408323.html
Copyright © 2011-2022 走看看