zoukankan      html  css  js  c++  java
  • 【2020 杭电多校第四场】Go Running 最小点覆盖

    Go Running

    题意

    现在有好多人在坐标轴上跑步,没有固定的起点,每个人可以随机出现在坐标轴上,他们移动的方式是固定的,给出 n 个时间和坐标的对应,表示在这个时间,这个位置最少有 1 个人,问现在跑步的最少有多少个人。

    思路

    比赛的时候一想哪些人可能是同一个人?x + t 或者x - t 相同的地方,有可能是同一个人。

    我们把 x + t 相同的放在一起,x - t 相同的放在一起。

    这时就是选择数量最小的 x - t , x + t ,覆盖所有的点,然后就懵了。。。

    做这题总有一种熟悉的感觉,但就是不知道哪熟悉。

    按照我的思路这就类似于最小集合覆盖问题,唯一的区别是一个点被两个集合覆盖。

    正解是二分图。

    参考博客2020杭电多校第四场 1007 Go Running Dinic最大流跑二分图匹配

    今天看了看博客,又重新看了点覆盖的定义。

    点覆盖,在图论中点覆盖的概念定义如下:对于图G=(V,E)中的一个点覆盖是一个集合S⊆V使得每一条边至少有一个端点在S中。

    现在我们选择最少的 x - t 和 x + t ,使得 n 个点都和它们有关系,就是最小点覆盖,每个点的 x - t 和 x + t 一定要存在一个,x - t 和 x + t 相连建好边之后,形成的最小点覆盖,就满足条件。

    H-K算法 代码

    #include <bits/stdc++.h>
    #define fuck system("pause")
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int N = 2e5 + 10;
    int boy[N], girl[N], disx[N], disy[N], used[N];
    
    vector<int> xiao[N], vec1,vec2;
    int getid1(int x){
        return lower_bound(vec1.begin(), vec1.end(), x) - vec1.begin() + 1;
    }
    int getid2(int x){
        return lower_bound(vec2.begin(), vec2.end(), x) - vec2.begin() + 1;
    }
    struct node{
        int t, pos;
    } arr[N];
    int n, m, dis;
    bool search()
    {
        for (int i = 1;i<=n;i++){ 
            disx[i] = disy[i] = -1;
        }
        queue<int> q;
        dis = inf; 
        for (int i = 1; i <= m; i++) 
        {
            if (boy[i] == -1) {
                q.push(i);
                disx[i] = 0; 
            }
        }
        while (!q.empty()) {
            int u = q.front(); 
            q.pop();
            if (disx[u] > dis)
                continue;
            for (int i = 0; i < xiao[u].size(); i++) 
            {
                int v = xiao[u][i];
                if (disy[v] == -1) 
                {
                    disy[v] = disx[u] + 1; 
                    if (girl[v] == -1) 
                        dis = disy[v]; 
                    else {
                        disx[girl[v]] = disy[v] + 1; 
                        q.push(girl[v]);
                    }
                }
            }
        }
        return dis != inf;
    }
    int find(int x)
    {
        for (int i = 0; i < xiao[x].size(); i++) {
            int v = xiao[x][i];
            if (used[v] == 0 && disy[v] == disx[x] + 1) 
            {
                used[v] = 1;
                if (girl[v] != -1 && disy[v] == dis)
                    continue; 
                if (girl[v] == -1 || find(girl[v])) 
                {
                    girl[v] = x;
                    boy[x] = v;
                    return 1;
                }
            }
        }
        return 0;
    }
    int match()
    {
        int ans = 0;
        for (int i = 1; i <= n;i++){
            boy[i] = girl[i] = -1;
        }
        while (search()) 
        {
            for (int i = 1;i<=n;i++)
                used[i] = 0;
            for (int i = 1; i <= m; i++) 
            {
                if (boy[i] == -1)
                    ans += find(i);
            }
        }
        return ans;
    }
    int main()
    {
        // freopen("D:\G.in","r",stdin);
        // freopen("D:\my.out","w",stdout);
        int T;
        scanf("%d", &T);
        while(T--){
            vec1.clear(), vec2.clear();
            scanf("%d", &n);
            for (int i = 1; i <= n;i++){
                xiao[i].clear();
                scanf("%d%d", &arr[i].pos, &arr[i].t);
                vec1.pb(arr[i].pos - arr[i].t);
                vec2.pb(arr[i].pos + arr[i].t);
            }
            sort(vec1.begin(), vec1.end()), sort(vec2.begin(), vec2.end());
            vec1.erase(unique(vec1.begin(), vec1.end()), vec1.end());
            vec2.erase(unique(vec2.begin(), vec2.end()), vec2.end());
            m = n;
            for (int i = 1; i <= n;i++){
                int x = getid1(arr[i].pos - arr[i].t);
                int y = getid2(arr[i].pos + arr[i].t);
                xiao[x].pb(y);
            }
            int ans = match();
            printf("%d
    ", ans);
        }
        // fuck;
        return 0;
    }
    
  • 相关阅读:
    OD: Memory Attach Technology
    Chrome: Shockwave Flash isn't responding
    OD: Memory Attach Technology
    OD: Heap Exploit : DWORD Shooting & Opcode Injecting
    OD: Heap in Windows 2K & XP SP1
    OD: Writing Small Shellcode
    OD: Shellcode Encoding
    Set Windows IP by Batch
    OD: Universal Shellcode
    XenServer 使用笔记
  • 原文地址:https://www.cnblogs.com/valk3/p/13410597.html
Copyright © 2011-2022 走看看