zoukankan      html  css  js  c++  java
  • HDU1054 Strategic Game(二分匹配)

    题意:

    给你一个图,然后每个点被覆盖的时候,相邻的点也会被覆盖

    求最小的数量使所有点被覆盖

    思路:

    学树形dp的时候做过这道题了,绝对比二分图快。。

    现在刷二分图,n=1500,用匈牙利和HK算了下

    先上匈牙利。。624ms

    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/17 11:42:42
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int N=1510;
    int link[N];
    bool vis[N];
    vector<int>eg[N];
    bool dfs(int u)
    {
        for(int i=0;i<eg[u].size();i++)
        {
            int v=eg[u][i];
            if(!vis[v])
            {
                vis[v]=1;
                if(link[v]==-1||dfs(link[v]))
                {
                    link[v]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n,x,y,k;
        while(~scanf("%d",&n))
        {
            memset(link,-1,sizeof(link));
            for(int i=0;i<n;i++)
                eg[i].clear();
            for(int i=0;i<n;i++)
            {
                scanf("%d:(%d)",&x,&k);
                while(k--)
                {
                    scanf("%d",&y);
                    eg[x].push_back(y);
                    eg[y].push_back(x);
                }
            }
            int ans=0;
            for(int i=0;i<n;i++)
            {
                memset(vis,0,sizeof(vis));
                ans+=dfs(i);
            }
            printf("%d
    ",ans/2);
        }
        return 0;
    }

    然后是我的大HK- -,327ms

    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/17 11:46:38
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int N=1510;
    const int inf=0x3f3f3f3f;
    vector<int>eg[N];
    int n;
    int mx[N],my[N];
    int dx[N],dy[N],dis;
    bool vis[N];
    bool bfs()
    {
        queue<int>q;
        dis=inf;
        memset(dx,-1,sizeof(dx));
        memset(dy,-1,sizeof(dy));
        for(int i=0;i<n;i++)
            if(mx[i]==-1)
            {
                q.push(i);
                dx[i]=0;
            }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            if(dx[u]>dis) break;
            for(int i=0;i<eg[u].size();i++)
            {
                int v=eg[u][i];
                if(dy[v]==-1)
                {
                    dy[v]=dx[u]+1;
                    if(my[v]==-1) dis=dy[v];
                    else
                    {
                        dx[my[v]]=dy[v]+1;
                        q.push(my[v]);
                    }
                }
            }
        }
        return dis!=inf;
    }
    bool dfs(int u)
    {
        for(int i=0;i<eg[u].size();i++)
        {
            int v=eg[u][i];
            if(!vis[v]&&dy[v]==dx[u]+1)
            {
                vis[v]=1;
                if(my[v]!=-1&&dy[v]==dis) continue;
                if(my[v]==-1||dfs(my[v]))
                {
                    my[v]=u;
                    mx[u]=v;
                    return 1;
                }
            }
        }
        return 0;
    }
    int MaxMatch()
    {
        int ans=0;
        memset(mx,-1,sizeof(mx));
        memset(my,-1,sizeof(my));
        while(bfs())
        {
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++)
                if(mx[i]==-1&&dfs(i))
                    ans++;
        }
        return ans;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int x,y,k;
        while(~scanf("%d",&n))
        {
            for(int i=0;i<n;i++)
                eg[i].clear();
            for(int i=0;i<n;i++)
            {
                scanf("%d:(%d)",&x,&k);
                while(k--)
                {
                    scanf("%d",&y);
                    eg[x].push_back(y);
                    eg[y].push_back(x);
                }
            }
            printf("%d
    ",MaxMatch()/2);
        }
        return 0;
    }
  • 相关阅读:
    Scrum学习总结
    1330. 翻转子数组得到最大的数组值
    LeetCode 中等题解(4)
    LeetCode 中等题解(3)
    LeetCode 中等题解(2)
    LeetCode 中等题解(1)
    【暑期实习】计算机视觉岗问题整理-腾讯
    【暑期实习】计算机视觉岗问题整理-快手
    【暑期实习】计算机视觉岗问题整理-阿里
    Leetcode 1329. 将矩阵按对角线排序 题解
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5500944.html
Copyright © 2011-2022 走看看