pku 1486 求出二分匹配图中的必须边
开始楞是没看懂意思,E文让我很纠结...
要判断一条边是否为二分图中必须边,方法如下:
1、先求出原图的任意最大匹配
2、对二分图某一边的所有点,删去其当前的匹配边。删的过程不是简单的将原图设为不连通,你还得将其相应的匹配值设为未匹配。
假如原图link[a]=b; 那我们删边的时候既要讲map[b][a]设为0.,同时也要讲link[a]设为-1。(举个例子而已,数据的写法自己定)
3、对此跟新图再次从b点(承接上面的例子)进行一次最大匹配,如果此时还能完成最大匹配,那么刚才删去的那条边显然就不是必须边了。反之,必须边成立!(做完记得将图还原)
4、重复2步骤,直到所有的点都被删过了一次当前匹配边
(还有一个问题就是,再对跟新图进行最大匹配验证的过程中,这必然不可避免的会改变其他匹配边原来的信息。比如a点原来匹配着b点,在新方案中,它可能却变成了匹配c点。其实这对我们的算法没有任何影响,因为我们本来的目的就只是对点进行匹配,至于该点和那个点匹配,无所谓。最开始,我们也是任意的进行了一次二分匹配。我们删边的目的只是为了验证该点是不是还存在着其他匹配方案,至于是从哪一个方案变到哪一个方案,没有任何关系)
#include<iostream>#include<string>using namespace std; int link[30];int map[30][30];typedef struct node{int xmin;int xmax;int ymin;int ymax;}node; node num[30];int n,m;int v[30]; int find(int x){for(int i=1;i<=n;i++) {if(!v[i] && map[x][i]) { v[i]=1;if(link[i]==0 || find(link[i])) { link[i]=x;return 1; } } }return 0;} void solve(){int i; memset(link,0,sizeof(link));for(i=1;i<=n;i++) { memset(v,0,sizeof(v)); find(i); }} int isok(int x,int y,int i){if(x>=num[i].xmin && x<=num[i].xmax && y>=num[i].ymin && y<=num[i].ymax)return 1;return 0;} int main(){int i,j,a,b;m=1; freopen("D:\\in.txt","r",stdin);while(scanf("%d",&n),n) {for(i=1;i<=n;i++) { scanf("%d%d%d%d",&num[i].xmin,&num[i].xmax,&num[i].ymin,&num[i].ymax); } memset(map,0,sizeof(map));for(i=1;i<=n;i++) { scanf("%d%d",&a,&b);for(j=1;j<=n;j++) {if(isok(a,b,j)) { map[i][j]=1; //左边代表数字,右边代表字母 } } } //先任意求一次最大匹配 solve(); printf("Heap %d\n",m++);int flag=0;for(i=1;i<=n;i++) {if(!link[i])continue;int temp=link[i]; link[i]=0; //把位置腾出来 map[temp][i]=0; //同时把边删掉,这样就无法达到原来的匹配 memset(v,0,sizeof(v));if(!find(temp)) //如果没有新的匹配方案诞生,说明这是一条关键边 {if(flag) cout<<" "; flag=1; link[i]=temp; printf("(%c,%d)",(char)(i+64),temp); } map[temp][i]=1; //把图复原 }if(!flag) { cout<<"none"; } cout<<endl<<endl; }return 0;}
转载于:https://www.cnblogs.com/ka200812/archive/2011/07/30/2121866.html
pku 1486 求出二分匹配图中的必须边相关推荐
- ACMNO.39 分解质因数 求出区间[a,b]中所有整数的质因数分解。蓝桥杯训练!
题目描述 求出区间[a,b]中所有整数的质因数分解. 输入 输入两个整数a,b. 输出 每行输出一个数的分解,形如k=a1*a2*a3...(a1< =a2< =a3...,k也是从小到大 ...
- Java黑皮书课后题第7章:7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则最小
7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则返回最小的下标) 题目 题目描述 ...
- Java黑皮书课后题第7章:7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值
7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值 题目 题目描述与运行示例 破题 代码 ...
- C语言试题四十三之求出ss所指字符串中指定字符的个数,并返回此值。
1. 题目 请编写一个函数function,它的功能是:求出ss所指字符串中指定字符的个数,并返回此值. 2 .温馨提示 C语言试题汇总里可用于计算机二级C语言笔试.机试.研究生复试中C程序设计科目. ...
- JAVA 求出自然数101~199中的所有素数,每行显示10个数
课后习题练习 2.2 编程求出自然数101~199中的所有素数,每行显示10个数 2.3 编程顺序输出1~100之间所有能被7整除的整数 2.2 int num = 0, flag = 1;int b ...
- 【JAVA】求出区间[a,b]中所有整数的质因数分解。
问题描述 求出区间[a,b]中所有整数的质因数分解. 输入格式 输入两个整数a,b. 输出格式 每行输出一个数的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是从小 ...
- 使用天平只用3次求出12个球中的次品球并确认轻重
问题描述 有12个外观完全一样的球,其中有一个是次品球,质量与其他11质量不同.现要给你一台天平,你可否只用三次称量就找出这个球,并说明这个球比其他球重还是轻. 分析 如果已知轻重,通过天台求于12个 ...
- C语言:向一个数组输入数据,并求出该整形数组中的最大值(vs)
一,问题:找出该数组中最大的数: 二:思路: (1)可以通过"遍历数组"的方式实现该问题 三,实现过程: (1)先用sizeofarr定义该整型数组实际的元素长度: (2)在向实际 ...
- 求出2个字符串中的最大公共子串
给定字符串A和B,输出A和B中的最大公共子串. 比如A="aocdfe" B="pmcdfa" 则输出"cdf" void comm ...
最新文章
- 棋盘游戏的人工智能(二)------剪支
- javascript事件模型框架
- lua 收不到服务器发来消息,lua 学习之错误处理
- RocketMQ削峰
- 使用webpack搭建个性化项目
- Java包命名规则_包命名规范
- POJ 1088-滑雪
- editor does not contain a main type的解决方案
- 在SQL Server中解析和旋转定界数据
- 第四章 Python 外壳 :代码结构
- Protel 介绍 protel99se正式汉化版下载 Protel DXP2004简体中文版
- mysql 经纬度范围_MySQL之根据经纬度查询多少公里范围内的数据
- 计算机文管二级试题,计算机文管二级试题
- Formality使用总结1
- Java实现 蓝桥杯 算法训练 天数计算
- 智能对话机器人实战开发(1)- 体系结构和分类
- Tapd 快试试自定义字段+需求视图+报表,轻松研发管理
- 深度|SHEIN:长期主义的胜利
- 高德地图获取行政区域以及中心点
- ogc是一个非营利性组织_重新设计非盈利性咨询网站的案例研究
热门文章
- Linux实战教学笔记49:Zabbix监控平台3.2.4(一)搭建部署与概述
- 专访Connolly:为什么我们需要手动回归测试宣言?
- FileReader对象和FormData对象
- Modbus RTU 通信工具设计
- 美国国防部黑客大比武 “白帽黑客”受邀请
- Spring MVC 实现原理
- DNS服务器之简单配置(一)
- 如何让LINUX程序运行在多CPU?
- Opencv中cvCopy() 和cvCloneImage()的区别
- windows下FileZilla使用sftp(SSH-2)