POJ 1719 Shooting Contest 二分匹配
2015-09-23 00:44
399 查看
题意:给你r*c(行*列)的格子,每一列有2个白色格子,其余为黑色。需要找m个点,
找完之后,每一列只能选一个白色格子,每一行至少一个白色格子。如果找到,输出这m个点所在的行,从第一列开始输出,结果不唯一。
思路:每一行与列匹配,余下的列就随便找一个,如果行都没有匹配,则输出NO。
找完之后,每一列只能选一个白色格子,每一行至少一个白色格子。如果找到,输出这m个点所在的行,从第一列开始输出,结果不唯一。
思路:每一行与列匹配,余下的列就随便找一个,如果行都没有匹配,则输出NO。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m; int vis[1000+5]; struct node { int oth; int v,next; }e[2000+5],E[1000+5]; int head[1000+5],cnt; int linker[1000+5]; void Init() { memset(head,-1,sizeof(head)); memset(linker,-1,sizeof(linker)); cnt=0; } void add(int a,int b) { e[cnt].v=b; e[cnt].next=head[a]; head[a]=cnt++; } void Input() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d %d",&E[i].oth,&E[i].v); add(E[i].oth,i); add(E[i].v,i); } } int dfs(int u) { for(int i=head[u];i+1;i=e[i].next) { int v=e[i].v; if(!vis[v]) { vis[v]=1; if(linker[v]==-1||dfs(linker[v])) { linker[v]=u; return 1; } } } return 0; } void treatment() { int res=0; for(int i=1;i<=n;i++) { if(head[i]==-1) continue; memset(vis,0,sizeof(vis)); res+=dfs(i); } if(res!=n) printf("NO\n"); else { for(int i=1;i<=m;i++) { int ans; if(linker[i]==-1) ans=E[i].oth; else ans=linker[i]; if(i==1) printf("%d",ans); else printf(" %d",ans); } printf("\n"); } } int main() { int t; scanf("%d",&t); while(t--) { Init(); Input(); treatment(); } return 0; }
相关文章推荐
- C++ STL之stack queue 作者csdn账号 liuhmmjj
- java反射机制
- Nginx配置文件nginx.conf中文详解(总结)
- Hadoop家族
- mac jdk 6设置
- const常量和#define宏常量的区别
- 关于规划的寓言故事:把一张纸折叠51次 ------意义不在折纸,而在规划,重在规划!!!
- MAC 如何在MAC系统中保存txt格式文本
- 进程监控程序的开发(程序运行监控)
- HDU_3667_Transportation(最小费用流)
- JavaScript----数字转换字符串&字符串转发数字
- (奶油小刀插件) android-butterknife-zelezny 插件使用
- Android 网络编程
- CentOS 6 使用 yum 安装MongoDB及服务器端配置
- spfa算法
- 自定义的一个分页类
- 【UIKit-124-3】#import <UIKit/UIView.h>
- Acdream 1667 调皮的数一 (ACdreamer java 专场)
- HDU1231最大连续子序列(动态规划)
- 对称加密和非对称加密