【图论】【二分图匹配】[POJ 3041]Asteroids
2015-07-28 15:43
435 查看
首先这道题目可以发现我们可以发现如果集合SS表示所有需要被覆盖的点的行和列的集合那么我们的任务就是从SS中选出一个子集使得size(S′)size(S')最小同时S′S'可以覆盖所有的点。那么如果我们选择了一个行那么和当前行相关的所有的列都有可能不被再选,那么将当前行和当前行上所有点的列连接,那么我们求得就是一个最小点的覆盖集,那么ans=ans′ans=ans'
[code]#include <cstdio> #include <cstring> #include <algorithm> //#include <conio.h> using namespace std; const int MAXN = 1000; bool vis[MAXN+10]; int con[MAXN+10]; int endcnt; int n, m; struct node{ int v; node *next; }Edges[10000*2+10], *adj[MAXN+10], *ecnt=Edges; void addedge(int u, int v){ ++ecnt; ecnt->v = v; ecnt->next = adj[u]; adj[u] = ecnt; } bool dfs(int u){ for(node *p=adj[u];p;p=p->next){ if(!vis[p->v]){ vis[p->v] = true; if(con[p->v]==-1 || dfs(con[p->v])){ con[u] = p->v; con[p->v] = u; return true; } } } return false; } int work(){ int ret = 0; memset(con, -1, sizeof con); for(int i=1;i<=endcnt;i++) if(con[i] == -1){ memset(vis, 0, sizeof vis); ret += dfs(i); } return ret; } void read(){ int t1, t2; scanf("%d%d", &n, &m); for(int i=0;i<m;i++){ scanf("%d%d", &t1, &t2); addedge(t1, t2+n); addedge(t2+n, t1); } endcnt=n; } int main(){ int T=1; while(T--){ read(); printf("%d\n", work()); memset(adj, 0, sizeof adj); ecnt=Edges; } return 0; }
相关文章推荐
- 构造函数、复制构造函数、类型转换构造函数、析构函数
- easyui 改变下拉框高度
- 谈谈近期学习的感想 2015 7 28
- 一次ORACLE启动报错修复的记录
- app 常见网络性能
- 详解Objective-C的meta-class
- IOS即时通讯XMPP搭建openfire服务器
- eclipse 报错:GC overhead limit exceeded
- MVVM模式原则
- 将滚动条(scrollbar)保持在最底部的方法
- Unity NGUI灰化Shader
- 网络安全协议比较(PKI SSH SSL SET)
- android pull解析xml最简单的方法
- 简单使用输入/输出流
- ogre屏幕拾取
- 有感而发,生活
- IOS之富文本编辑
- php图像处理类实例
- 猴子背100根香蕉问题程序实现
- iOS开发实现页面的跳转与返回