UVA-11419 SAM I AM (最小点覆盖)
2015-11-05 22:24
218 查看
题目大意:在一个n*m的网格中,有k个目标,现在可以任选一行或列消除在其上的所有目标,求出最少选择次数及选法。
题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集。在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。
代码如下:
题目分析:经典的最小点覆盖问题,并且输出一个最小点覆盖集。在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; # define REP(i,s,n) for(int i=s;i<n;++i) # define CL(a,b) memset(a,b,sizeof(a)) # define CLL(a,b,n) fill(a,a+n,b) const int N=1005; struct Edge { int to,nxt; }; Edge e[N*N]; int link ,visx ,visy ,vis[2*N],mark ; int cnt,n,m,head ; void add(int u,int v) { e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt++; } void dfs1(int x) { visx[x]=1; for(int i=head[x];i!=-1;i=e[i].nxt){ int y=e[i].to; if(visy[y]) continue; visy[y]=1; dfs1(link[y]); } } bool dfs(int x) { for(int i=head[x];i!=-1;i=e[i].nxt){ int y=e[i].to; if(vis[y]) continue; vis[y]=1; if(link[y]==-1||dfs(link[y])){ link[y]=x; return true; } } return false; } int match() { int res=0; REP(i,1,n+1){ CL(vis,0); if(dfs(i)) ++res; } return res; } int main() { int a,b,k; while(scanf("%d%d%d",&n,&m,&k)&&(n+m+k)) { cnt=0; CL(head,-1); CL(link,-1); CL(mark,0); CL(visx,0); CL(visy,0); while(k--) { scanf("%d%d",&a,&b); add(a,b); } int ans=match(); REP(i,1,m+1) if(link[i]!=-1) mark[link[i]]=1; REP(i,1,n+1) if(!mark[i]) dfs1(i); printf("%d",ans); REP(i,1,n+1) if(!visx[i]) printf(" r%d",i); REP(i,1,m+1) if(visy[i]) printf(" c%d",i); printf("\n"); } return 0; }
相关文章推荐
- hdu 5443 The Water Problem
- windows 安装vim过程记录
- maven更改仓库地址
- maven更改仓库地址
- android 6.0 Runtime Permissions Check
- Ubuntu下查看CPU、内存和硬盘详细信息的命令
- iOS开发开题篇之 MVC 和MVVM
- 烂泥:haproxy学习之https配置
- 控件设置监听器的一些方法
- 如果像招聘程序员那样招聘木匠
- 换本书,继续学
- 国内IT公司病种,需要合理协调,共同进步,才能不被嘈乱的世道所唾弃
- R.anim.slide_in_right错误解决
- C++primer第五版第五章学习笔记
- 重拾信心,持之以恒
- <蓝牙BLE>cc2540主机获取数据包
- iOS 网络编程
- php download断点
- 第1章 Java中常用字符串方法总结
- Eclipse 跟Intellij IDEA 快捷键比较