zoukankan      html  css  js  c++  java
  • POJ 3041-Asteroids-二分图匹配

    题意:经典的二分图匹配问题。给出一个N*N矩阵,其中有K个障碍物。一发歼星炮可以清楚一行或者一列上的障碍物。求最少的开炮数。

    做法:可以考虑最大点覆盖。建图左边顶点为行,右边顶点为列。若有障碍物则连边。此时最大点覆盖就是最小开炮数,也就是计算二分图最大匹配。使用匈牙利算法即可。

     1 /*--------------------------------------------------------------------------------------*/
     2 //        Helica's header 
     3 //        Second Edition
     4 //        2015.11.7
     5 //
     6 #include <algorithm>
     7 #include <iostream>
     8 #include <cstring>
     9 #include <ctype.h>
    10 #include <cstdlib>
    11 #include <cstdio>
    12 #include <vector>
    13 #include <string>
    14 #include <queue>
    15 #include <stack>
    16 #include <cmath>
    17 #include <set>
    18 #include <map>
    19 
    20 //debug function for a N*M array 
    21 #define debug_map(N,M,G) printf("
    ");for(int i=0;i<(N);i++)
    22 {for(int j=0;j<(M);j++){
    23 printf("%d",G[i][j]);}printf("
    ");}                
    24 //debug function for int,float,double,etc.
    25 #define debug_var(X) cout<<#X"="<<X<<endl;
    26 /*--------------------------------------------------------------------------------------*/
    27 using namespace std;
    28 
    29 const int maxn = 500+10;
    30 int uN,vN;
    31 int G[2*maxn][2*maxn],linker[maxn];
    32 bool used[maxn];
    33 
    34 bool dfs(int u)
    35 {
    36     for(int v=1;v<=vN;v++)
    37     {
    38         if(G[u][v]&& !used[v])
    39         {
    40             used[v] = true;
    41             if(linker[v] == -1 || dfs(linker[v]))
    42             {
    43                 linker[v] = u;
    44                 return true;
    45             }
    46         }
    47     }
    48     return false;
    49 }
    50 
    51 int hungary()
    52 {
    53     int res = 0;
    54     memset(linker,-1,sizeof linker);
    55     for(int u=1;u<=uN;u++)
    56     {
    57         memset(used,false,sizeof(used));
    58         if(dfs(u)) res++;
    59     }
    60     return res;
    61 }
    62 
    63 int N,K,M,T;
    64 
    65 int main()
    66 {
    67     while(~scanf("%d%d",&N,&K))
    68     {
    69         memset(G,0,sizeof G);
    70         uN = vN = N;
    71         for(int i=0;i<K;i++)
    72         {
    73             int x,y;
    74             scanf("%d%d",&x,&y);
    75             G[x][y] = 1;
    76         }
    77         printf("%d
    ",hungary());
    78     }    
    79 }
  • 相关阅读:
    二 .数据库(Data)操作
    一. 数据库(Data)基础
    五种IO/模型
    并发编程 (协程)
    七.并发编程 (线程池,返回值,回调函数)
    六.并发编程 (线程对列)
    五.并发编程 (线程事件)
    四.并发编程 (线程信号量)
    三.并发编程 (线程锁)
    二.并发编程 (程序中线程操作)
  • 原文地址:https://www.cnblogs.com/helica/p/5243933.html
Copyright © 2011-2022 走看看