• 【最小点覆盖】POJ3041-Asteroids


    【题目大意】

    在n*n的网格上有n个点,每次删除一行或者一列,问至少要删除几次才能删除完全部的这些店?

    【思路】

    在国庆最后一天到来前,把二分图的三个基本情况【最小点覆盖】【DAG图的最小路径覆盖】和【二分图的最大独立集】全部复习了一遍。

    这道题是非常典型的最小点覆盖,指的是用最少的点让每条边都至少和两个集合中的某一个点关联。

    最小点覆盖=二分图最大匹配数。

    对于这道题而言,我们把横坐标作为集合X,纵坐标作为集合Y,对于点(x,y),由X中的x连向Y中的y。对于每条边,只要x和y中有一个被删除即可,明显的最小点覆盖模型。

    十分钟水~

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 const int MAXN=505;
     8 vector<int> E[MAXN];
     9 int lk[MAXN],vis[MAXN],n,k; 
    10 
    11 int find(int u)
    12 {
    13     for (int i=0;i<E[u].size();i++)
    14     {
    15         int v=E[u][i];
    16         if (!vis[v])
    17         {
    18             vis[v]=1;
    19             if (!lk[v]||find(lk[v]))
    20             {
    21                 lk[v]=u;
    22                 return 1;
    23             }
    24         }
    25     }
    26     return 0;
    27 }
    28 
    29 void init()
    30 {
    31     scanf("%d%d",&n,&k);
    32     for (int i=1;i<=k;i++)
    33     {
    34         int x,y;
    35         scanf("%d%d",&x,&y);
    36         E[x].push_back(y);
    37     }
    38 }
    39 
    40 void solve()
    41 {
    42     int ans=0;
    43     memset(lk,0,sizeof(lk));
    44     for (int i=1;i<=n;i++)
    45     {
    46         memset(vis,0,sizeof(vis));
    47         if (find(i)) ans++;
    48     }
    49     printf("%d",ans);
    50 } 
    51 
    52 int main()
    53 {
    54     init();
    55     solve();
    56     return 0;
    57 }
  • 相关阅读:
    Redis面试题
    redis基本操作
    pwd命令和cd命令
    ls命令详解
    Python时间操作所相关
    Nginx
    网络相关知识
    LeetCode 刷题记录(6-10题)
    绕过校园网Web认证
    Java相关知识
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5935133.html
Copyright © 2020-2023  润新知