• hdu1054 简单最小顶点覆盖


    题意:
          给你一些点,和一些边,如果把一个点安装保护装置,那么与他直接相连的点就可以被保护,题目问的是最少安装多少个点能让所有的点都被保护。

    思路:

          这是最基础的二分图最少定点覆盖,对于可以保护的点,我们只要找到最大的匹配次数,也就是最少的安置个数就行了,直接一遍匈牙利,注意的一点是建图的时候记得建双向边,最后答案要除以2,因为a->b b->a 匹配数是2。


    #include<stdio.h>
    #include<string.h>
    
    #define N_node 1550
    #define N_edge 2255000
    
    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 ,i ,ans ,nn ,from ,to;
       while(~scanf("%d" ,&n))
       {
          memset(list ,0 ,sizeof(list)) ,tot = 1;
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%d:(%d)" ,&from ,&nn);
             while(nn--)
             {
                scanf("%d" ,&to);
                add(from + 1 ,to + 1);
                add(to + 1 ,from + 1);
             }
          }
          memset(mk_gx ,255 ,sizeof(mk_gx));
          ans = 0;
          for(i = 1 ;i <= n ;i ++)
          {
             memset(mk_dfs ,0 ,sizeof(mk_dfs));
             ans += DFS_XYL(i);
          }
          printf("%d
    " ,ans / 2);
       }
       return 0;
    } 
    

  • 相关阅读:
    C#线程类Thread初步
    无限级分类存储过程版
    C#多线程编程实例实战
    数据库里阻塞和死锁情况 看那里死锁的存储过程
    预防按钮的多次点击 恶意刷新
    .net2.0文件压缩/解压缩
    HttpHandler和HttpModule入门
    反射,枚举,绑定下拉框
    在C#里关于定时器类
    判断上传的图片文件格式是否合法不是用后缀做的判断
  • 原文地址:https://www.cnblogs.com/csnd/p/12062962.html
Copyright © 2020-2023  润新知