POJ3041 最小顶点覆盖

题意:
      给你一个n * n 的矩阵,和X所在的坐标,问你最少放多少个**可以把图里的所有X都覆盖,每个**可以覆盖一行,或者一列。


思路:
      最小顶点覆盖,最小顶点覆盖=二分匹配,每一行最多放一个,每一列最多放一个,对于每一个点,他只要被一行或者一列照应就行了。

所以直接把X所在的点的行和列连接在一起,(二分后对于当前点相当于只选择一个),这样最后每个点都会被照应到,同时尽可能地去匹配了,也就是尽可能地减少了浪费。


#include<stdio.h>
#include<string.h>

#define N_node 550
#define N_edge 255000

typedef struct
{
    int to ,next;
}STAR;

STAR E[N_edge];
int list[N_node] ,tot;
int mk_dfs[N_node] ,mk_gx[N_node];

void add(int a ,int b)
{
   E[++tot].to = b;
   E[tot].next = list[a];
   list[a] = tot;
}

int DFS_XYL(int x)
{
    for(int k = list[x] ;k ;k = E[k].next)
    {
       int to = E[k].to;
       if(mk_dfs[to]) continue;
       mk_dfs[to] = 1;
       if(mk_gx[to] == -1 || DFS_XYL(mk_gx[to]))
       {
          mk_gx[to] = x;
          return 1;
       }
    }
    return 0;
}

int main ()
{
    int n ,m ,i;
    int a ,b;
    while(~scanf("%d %d" ,&n ,&m))
    {
       memset(list ,0 ,sizeof(list));
       tot = 1;
       for(i = 1 ;i <= m ;i ++)
       {
          scanf("%d %d" ,&a ,&b);
          add(a ,b);
       }
       int sum = 0;
       memset(mk_gx ,255 ,sizeof(mk_gx));
       for(i = 1 ;i <= n ;i ++)
       {
          memset(mk_dfs ,0 ,sizeof(mk_dfs));
          sum += DFS_XYL(i);
       }
       printf("%d
" ,sum);
    }
    return 0;
}



原文地址:https://www.cnblogs.com/csnd/p/12063072.html