2020牛客暑期多校训练营Day1 1or2(1还是2)

题目描述:
Bobo has a graph with n vertices and m edges where the i-th edge is between the vertices ai and bi​. Find out whether is possible for him to choose some of the edges such that the i-th vertex is incident with exactly di​ edges.
输入:
2 1
1 1
1 2
2 1
2 2
1 2
3 2
1 1 2
1 3
2 3
输出:
Yes
No
Yes
题目大意:
给你m条边,n个点,要从m条边中选择一部分,和n个点构成一张图,是否能在满足每个点正好连有d[i]条边的情况下完成,能完成输出Yes,不能输出No
??直接统计加入所有边后的入度出度,看看是不是比d[i]大不就行了?
还真不行。度是针对于点去统计的,这个题则是去选择一些边,比如下图:在这里插入图片描述
假如,d[1]=2,d[2]=d[3]=d[4]=1,d[i]确实小于i的度但却是不成立的,所以不能单纯地去看度的大小,还要看匹配的情况:
窝的想法是,第i个点的每一个度都要跟相应的边去匹配,那么,不妨把边化成点,然后边和与其相连的点去连线,如下图:
在这里插入图片描述

可是这样做还是看不出明显的两两匹配,我们就想到,一条边是去连接两个点,因此匹配的时候需要两侧都匹配,所以对于每一条边应该去建两个虚点才行,如图:
在这里插入图片描述

哎?你看这个两两匹配就很明显了,比如说(1-2)那条边,建立了5和6两个虚点,5和1匹配,6和2匹配,那么说明这条边被加入图中了,再比如说(1-3)那条边,建立了7和8两个虚点,而7和8自身匹配了起来就说明这条边不会加入最后的图中
但是对上面的方法来讲都是在d[i]=1的情况下,d[i]大于1的时候,一个点已经不够了,所以我们需要对于第i个点,每有一个d[i]就多建立一个虚点,对于每一条边,如果这条边和第j个点相连,则需把那一侧的虚点和第j个点的所有虚点都相连,如图:
这组数据的答案是NO

如图,图中出现了一个没有被匹配上的点,所以答案是NO,再比如:
在这里插入图片描述

这组数据达到了完全匹配,所以是可以的。那么建图方法我就说完了,但是匹配······因为不是二分图,也就是说图中在增广路径的时候会出现奇环,所以需要另一种算法:带花树算法,用于普通图中的最大匹配。
带花树在下面这篇博客里可以找到:

接下来直接上代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define rt int
using namespace std;
inline rt read()
{
   
 register char ch=getchar();register rt u=0,v=0;
 while(!isdigit(ch)){
   if(ch=='-')v=1;ch=getchar();}
 while(isdigit(ch)){
   u=u*10+ch-'0';ch=getchar();}
 return v?-u:u;
}
const rt maxn=505;
const rt maxm=maxn*maxn*2;
rt d[maxn]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值