zoukankan      html  css  js  c++  java
  • 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;
    }
    
    


  • 相关阅读:
    欧拉回路
    2018 年 ACM-ICPC 焦作站现场赛感受
    3.1 基础-抛小球
    2.2 进阶-禁忌雷炎
    初学Java-循环输入直到文件结束
    1.1 基础-取近似值
    1.2 进阶-对称的二叉树
    LEETCODE
    算法
    算法
  • 原文地址:https://www.cnblogs.com/csnd/p/12063073.html
Copyright © 2011-2022 走看看