zoukankan      html  css  js  c++  java
  • HDU 6808 Go Running(二分图最小顶点覆盖)

    题意:给出N个元组(x, y)问最多需要多少个初始状态才能转移到这样,一个元组(x,y)可以一直向右转移(x+1, y+1)...(x+i, y+i)或者一直向左转移(x+i, y-i)。n<1e5, x,y<1e9

    题解:选择最少的直线,能够包括所有给定的点(x,y),把斜率1和-1的直线分别作为二分图u,v部分,当前有(x,y)即对两条直线加边,求的即是二分图的最小顶点覆盖。

       二分图最小顶点覆盖定义:假如选了一个点就相当于覆盖了以它为端点的所有边。最小顶点覆盖就是选择最少的点来覆盖所有的边。

    HK算法:

    #include <bits/stdc++.h>
    #define IO_read ios::sync_with_stdio(false);cin.tie(0)
    #define fre freopen("C:\in.txt", "r", stdin)
    #define _for(i,a,b) for(int i=a; i< b; i++)
    #define _rep(i,a,b) for(int i=a; i<=b; i++)
    #define inf 0x3f3f3f3f
    #define lowbit(a) ((a)&-(a))
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x)
    {
        char c; bool op=0;
        while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
        x=c-'0';
        while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
        if(op) x=-x;
    }
    template <class T>
    void write(T x)
    {
        if(x<0) putchar('-'), x=-x;
        if(x>=10) write(x/10);
        putchar('0'+x%10);
    }
    
    const int maxn=1e5+5;
    unordered_map<int, int> line1, line2;
    int T, n;
    
    /* //hungry算法复杂度:VE TEL
    vector<int> g[maxn];
    int un, vn;
    int linker[maxn], used[maxn];
    
    bool dfs(int u)
    {
        for(auto &v: g[u]){
            if(!used[v]){
                used[v]=true;
                if(linker[v]==-1 || dfs(linker[v])){
                    linker[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hungry()
    {
        int res=0;
        memset(linker, -1, sizeof(linker));
        for(int u=1; u<=un; u++){
            memset(used, 0, sizeof(used));
            if(dfs(u)) res++;
        }
        return res;
    }
    */
    
    // hk算法时间复杂度sqrt(V)*E
    vector<int> g[maxn];
    int un, vn;
    int linker[maxn], used[maxn];
    int mx[maxn], my[maxn], dx[maxn], dy[maxn], dis;
    
    bool search_path()
    {
        queue<int> que;
        dis=inf;
        memset(dx, -1, sizeof(dx));
        memset(dy, -1, sizeof(dy));
        for(int u=1; u<=un; u++){
            if(mx[u]==-1) que.push(u), dx[u]=0;
        }
        while(!que.empty())
        {
            int u=que.front(); que.pop();
            if(dx[u]>dis) break;
            for(auto &v: g[u]){
                if(dy[v]==-1){
                    dy[v]=dx[u]+1;
                    if(my[v]==-1) dis=dy[v];
                    else dx[my[v]]=dy[v]+1, que.push(my[v]);
                }
            }
        }
        return dis!=inf;
    }
    
    bool dfs(int u)
    {
        for(auto &v: g[u])
        {
            if(!used[v] && dy[v]==dx[u]+1){
                used[v]=true;
                if(my[v]!=-1 && dy[v]==dis) continue;
                if(my[v]==-1 || dfs(my[v])){
                    my[v]=u, mx[u]=v;
                    return true;
                }
            }
        }
        return false;
    }
    
    int hopcroft_karp()
    {
        int res=0;
        memset(mx, -1, sizeof(mx));
        memset(my, -1, sizeof(my));
        while(search_path()){
            memset(used, 0, sizeof(used));
            for(int u=1; u<=un; u++)
                if(mx[u]==-1 && dfs(u)) res++;
        }
        return res;
    }
    
    
    int main()
    {
        read(T);
        while(T--)
        {
            read(n);
            un=vn=0;
            _rep(i, 1, n) g[i].clear();
            line1.clear(), line2.clear();
            int x, y;
            _rep(i, 1, n){
                read(x), read(y);
                int k1=y-x, k2=y+x;
                if(!line1[k1]) line1[k1]=++un;
                if(!line2[k2]) line2[k2]=++vn;
                g[line1[k1]].push_back(line2[k2]);
            }
            //printf("%d
    ", hungry());
            printf("%d
    ", hopcroft_karp());
        }
        return 0;
    }
  • 相关阅读:
    奖券数目
    用jQuery和ajax实现搜索框文字自动补全功能
    简单的文件上传功能实现(java)
    示例演示公告通知标题无缝向上滚动,文字段落无缝向上滚动,简单的wangeditor富文本编辑器,简单的音乐播放demo
    SSM框架中注解含义及应用场景小结
    数据库优化以及SQL优化小结
    javaWEB中前后台乱码解决问题小结
    线程同步的方法
    MySQL的简单使用
    springMVC运行流程图及运行原理
  • 原文地址:https://www.cnblogs.com/Yokel062/p/13416845.html
Copyright © 2011-2022 走看看