博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3041 Asteroids (二分图最小点覆盖)
阅读量:4493 次
发布时间:2019-06-08

本文共 1628 字,大约阅读时间需要 5 分钟。

题目链接:

在一个n*n的地图中,有m和障碍物,你每一次可以消除一行或者一列的障碍物,问你最少消除几次可以将障碍物全部清除。

用二分图将行(左边)和列(右边)用障碍物联系起来,比如(2,3)有个障碍物,那么左边的2和右边的3连边。边的个数就是障碍物的个数,点的个数就是次数,所以问题就变成了用少的点覆盖全部的边,也就是最小点覆盖问题。二分图中,最小点覆盖=最大匹配数。

1 //最小点覆盖 = 最大匹配 2 #include 
3 #include
4 #include
5 #include
6 using namespace std; 7 const int N = 505; 8 struct Edge { 9 int next , to;10 }edge[N*N];11 int head[N] , cnt , match[N];12 bool vis[N];13 14 void init() {15 memset(match , -1 , sizeof(match));16 memset(head , -1 , sizeof(head));17 memset(vis , false , sizeof(vis));18 cnt = 0;19 }20 21 inline void add(int u , int v) {22 edge[cnt].next = head[u];23 edge[cnt].to = v;24 head[u] = cnt++;25 }26 27 bool dfs(int u) {28 for(int i = head[u] ; ~i ; i = edge[i].next) {29 int v = edge[i].to;30 if(!vis[v]) {31 vis[v] = true;32 if(match[v] == -1 || dfs(match[v])) {33 match[v] = u;34 return true;35 }36 }37 }38 return false;39 }40 41 int hungry(int n) {42 int res = 0;43 for(int i = 1 ; i <= n ; ++i) {44 memset(vis , false , sizeof(vis));45 if(dfs(i))46 res++;47 }48 return res;49 }50 51 int main()52 {53 int n , m , u , v;54 while(~scanf("%d %d" , &n , &m)) {55 init();56 for(int i = 0 ; i < m ; ++i) {57 scanf("%d %d" , &u , &v);58 add(u , v);59 }60 printf("%d\n" , hungry(n));61 }62 return 0;63 }

 

转载于:https://www.cnblogs.com/Recoder/p/5671524.html

你可能感兴趣的文章
mysql分表的3种方法(转)
查看>>
eclipse格式化代码样式
查看>>
asp uploadify示例下载
查看>>
1/7 第一篇 变量的内存实质
查看>>
jQuery遮罩插件jQuery.blockUI.js简介
查看>>
MaskedTextBox控件实现输入验证
查看>>
设计模式-行为型模式-中介者模式
查看>>
mount: 192.168.70.178:/ failed, reason given by server: Permission denied 问题
查看>>
如何清除自动保存的远程目录登录密码
查看>>
ios UIWebView自定义Alert风格的弹框
查看>>
AVERAGE和averageif函数
查看>>
php调试工具xdebug相关参数
查看>>
C# 编程的几个建议
查看>>
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
查看>>
归并排序
查看>>
怪异的CheckedListBox数据绑定
查看>>
重写与重载 java
查看>>
对js闭包的粗浅理解
查看>>
理解C++对象内存布局
查看>>
算法总结之 在两个排序数组中找到第K小的数
查看>>