zoukankan      html  css  js  c++  java
  • poj 3041 二分图最大匹配

    题意:给定一个NxN的网格,其中有k个格点上有障碍物,每次可以消除一行或一列障碍物,问最少几次可以消除全部的障碍物。

    思路:二分图的经典模型,将所有的行看作二分图中左边的端点,将所有的列看作右边的端点,当格点上有障碍物时,连一条边,问题转变为求二分图的最小顶点覆盖,根据König定理由二分图的最大匹配得到

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<sstream>
     8 #include<iomanip>
     9 #include<vector>
    10 #include<map>
    11 #include<set>
    12 #include<queue>
    13 using namespace std;
    14 const int MOD = 1e9 + 7;
    15 
    16 typedef long long LL;
    17 typedef unsigned long long ULL;
    18 
    19 const int maxn = 505;
    20 bool g[maxn][maxn];
    21 int link[maxn];
    22 bool check[maxn];
    23 
    24 int n;
    25 
    26 bool dfs(int u){
    27     for(int i = 1; i <= n; ++i){
    28          if(!check[i] && g[u][i]){
    29              check[i] = true;
    30              if(link[i] == -1 || dfs(link[i])){
    31                   link[i] = u;
    32                   return true;
    33              }
    34          }
    35     }
    36     return false;
    37 }
    38 
    39 int hungarian(){
    40     int ans = 0;
    41     memset(link,-1,sizeof(link));
    42     for(int i = 1; i <= n; ++i){
    43         memset(check,0,sizeof(check));
    44         if(dfs(i)) ++ans;
    45     }
    46     return ans;
    47 }
    48 
    49 int main(){
    50     int k;
    51     scanf("%d%d",&n,&k);
    52     int x,y;
    53     for(int i = 0; i < k; ++i){
    54          scanf("%d%d",&x,&y);
    55          g[x][y] = 1;
    56     }
    57     printf("%d
    ",hungarian());
    58     return 0;
    59 }
  • 相关阅读:
    Windows 7 X64位平台下,VC6调试运行程序,中断调试无法退出
    在Windows中安装MinGW-w64(有图,一步一步)
    自我修养
    Core 事件总
    异步消息
    微信小程序
    安装Zookeeper集群
    Linux删除非空目录
    adoop集群动态添加和删除节点
    安装和配置hadoop集群步骤
  • 原文地址:https://www.cnblogs.com/Pos-Proteus/p/5766514.html
Copyright © 2011-2022 走看看