【UOJ 79】 一般图最大匹配 (✿带花树开花)
从前一个和谐的班级,所有人都是搞OI的。有 n 个是男生,有 0 个是女生。男生编号分别为 1,…,n。
现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽。每个人至多属于一个小组。
有若干个这样的条件:第 v 个男生和第 u 个男生愿意组成小组。
请问这个班级里最多产生多少个小组?
输入格式
第一行两个正整数,n,m。保证 n≥2。
接下来 m 行,每行两个整数 v,u 表示第 v 个男生和第 u 个男生愿意组成小组。保证 1≤v,u≤n,保证 v≠u,保证同一个条件不会出现两次。
输出格式
第一行一个整数,表示最多产生多少个小组。
接下来一行 n 个整数,描述一组最优方案。第 v 个整数表示 v 号男生所在小组的另一个男生的编号。如果 v 号男生没有小组请输出 0。
样例一
input
10 20
9 2
7 6
10 8
3 9
1 10
7 1
10 9
8 6
8 2
8 1
3 1
7 5
4 7
5 9
7 8
10 4
9 1
4 8
6 3
2 5output
5
9 5 6 10 2 3 8 7 1 4样例二
input
5 4
1 5
4 2
2 1
4 3output
2
2 1 4 3 0限制与约定
1≤n≤500,1≤m≤124750
时间限制:1s
空间限制:256MB
【分析】
推荐博客:http://blog.csdn.net/yihuikang/article/details/10460997
http://blog.csdn.net/jackyguo1992/article/details/11271497
上模板:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 510
#define Maxm 1247501+100 int n; struct node
{
int x,y,next;
}t[Maxm*2];
int first[Maxn],len; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} int fa[Maxn],nt[Maxn],mark[Maxn],match[Maxn];
int vis[Maxn],nw;
int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} int merge(int x,int y)
{
fa[ffa(x)]=ffa(y);
} queue<int > q; //找环
int LCA(int x,int y)
{
nw++;
while(1)
{
if(x)
{
x=ffa(x);
if(vis[x]==nw) return x;
vis[x]=nw;
if(match[x]) x=nt[match[x]];
else x=0;
}
int tt=x;x=y;y=tt;
}
} //奇环缩点
void shrink(int x,int rt)
{
while(x!=rt)
{
int y=match[x],z=nt[y];
if(ffa(z)!=rt) nt[z]=y;
if(mark[y]==2) {q.push(y);mark[y]=1;}
if(mark[z]==2) {q.push(z);mark[z]=1;}
merge(x,y);merge(y,z);
x=z;
}
} void augment(int now)
{
nw=0;
for(int i=1;i<=n;i++)
nt[i]=0,vis[i]=0,mark[i]=0,fa[i]=i;
while(!q.empty()) q.pop();
q.push(now);mark[now]=1;
while(!q.empty())
{
int x=q.front();q.pop();
if(match[now]) return;//当前搜索节点找到增广路
for(int i=first[x];i;i=t[i].next)
{
int y=t[i].y;
if(match[x]==y||ffa(x)==ffa(y)) continue;
if(mark[y]==2) continue;
//奇环缩点
if(mark[y]==1)
{
int rt=LCA(x,y);
if(ffa(x)!=rt) nt[x]=y;
if(ffa(y)!=rt) nt[y]=x; shrink(x,rt);shrink(y,rt);
}
//增广
else if(!match[y])
{
nt[y]=x;
for(int j=y;j;)
{
int k=nt[j],z=match[k];
match[j]=k;match[k]=j;
j=z;
}
break;
}
//之前匹配过
else
{
nt[y]=x;
q.push(match[y]);
mark[match[y]]=1;
mark[y]=2;
}
}
}
} int main()
{
int m;
scanf("%d%d",&n,&m);
len=0;
memset(first,0,sizeof(first));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
int ans=0;
memset(match,0,sizeof(match));
for(int i=1;i<=n;i++) if(!match[i]) augment(i);
for(int i=1;i<=n;i++) if(match[i]) ans++;
ans/=2;
printf("%d\n",ans);
for(int i=1;i<=n;i++) printf("%d ",match[i]);
printf("\n");
return 0;
}
✿我认为所谓带花树的树,指匈牙利树,奇环缩点构成花✿
2017-03-04 11:26:08
【UOJ 79】 一般图最大匹配 (✿带花树开花)的更多相关文章
- UOJ #79 一般图最大匹配 带花树
http://uoj.ac/problem/79 一般图和二分图的区别就是有奇环,带花树是在匈牙利算法的基础上对奇环进行缩点操作,复杂度似乎是O(mn)和匈牙利一样. 具体操作是一个一个点做类似匈牙利 ...
- HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
一般图最大匹配带花树+暴力: 先算最大匹配 C1 在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2 假设C2+2==C1则这条边再某个最大匹配中 Boke and ...
- ZOJ 3316 Game 一般图最大匹配带花树
一般图最大匹配带花树: 建图后,计算最大匹配数. 假设有一个联通块不是完美匹配,先手就能够走那个没被匹配到的点.后手不论怎么走,都必定走到一个被匹配的点上.先手就能够顺着这个交错路走下去,最后一定是后 ...
- URAL1099. Work Scheduling(一般图匹配带花树开花算法)
1099. Work Scheduling Time limit: 0.5 second Memory limit: 64 MB There is certain amount of night gu ...
- 【UOJ #79】一般图最大匹配 带花树模板
http://uoj.ac/problem/79 带花树模板,做法详见cyb的论文或fhq的博客. 带花树每次对一个未盖点bfs增广,遇到奇环就用并查集缩环变成花(一个点),同时记录每个点的Next( ...
- uoj#79. 一般图最大匹配(带花树)
传送门 带花树 不加证明的说一下过程好了:每次从一个未匹配点\(S\)出发bfs,设\(S\)为\(1\)类点,如果当前点\(v\)在本次bfs中未经过,分为以下两种情况 1.\(v\)是未匹配点,那 ...
- 【learning】一般图最大匹配——带花树
问题描述 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...
- 【刷题】UOJ #79 一般图最大匹配
从前一个和谐的班级,所有人都是搞OI的.有 \(n\) 个是男生,有 \(0\) 个是女生.男生编号分别为 \(1,-,n\) . 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个 ...
- UOJ #79. 一般图最大匹配
板子: #include<iostream> #include<cstdio> #include<algorithm> #include<vector> ...
随机推荐
- ⑥ 设计模式的艺术-06.建造者(Builder)模式
场景 我们要建造一个复杂的产品.比如:神州飞船,Iphone.这个复杂的产品的创建.有这样一个问题需要处理: 装配这些子组件是不是有个步骤问题? 实际开发中,我们所需要的对象构建时,也非常复杂,有很多 ...
- 【BZOJ】1576 [Usaco2009 Jan]安全路经Travel
[算法]最短路树+(树链剖分+线段树)||最短路树+并查集 [题解] 两种方法的思想是一样的,首先题目限制了最短路树唯一. 那么建出最短路树后,就是询问对于每个点断掉父边后重新找路径的最小值,其它路径 ...
- Global.asax文件—ASP.NET细枝末节(1)
说明 Global的解释是全局的.全球的. Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法.你可以使用这个文件实现应用 ...
- 微信小程序开发(三)项目目录及文件结构
第二章我们已经创建了一个Hello WXapplet示例小程序.我们从文件目录结构来了解Hello WXapplet项目的构成. 目录结构显示,在小程序项目的根目录下面包含3个app开头的文件(app ...
- 4B/5B编码原理
4B/5B编码原理 什么是4B/5B编码? 4B/5B编码是百兆以太网(即快速以太网)中线路层编码类型之一,就是用5bit的二进制数来表示4bit二进制数,映射方式如下表所示: 为什么要进行4B/5B ...
- [MySQL] gap lock/next-key lock浅析
当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将锁细分为如下几种子类型: record lock (RK) 记录锁, 仅仅锁住索引记录的一行 ...
- python RSA加密解密及模拟登录cnblog
1.公开密钥加密 又称非对称加密,需要一对密钥,一个是私人密钥,另一个则是公开密钥.公钥加密的只能私钥解密,用于加密客户上传数据.私钥加密的数据,公钥可以解密,主要用于数字签名.详细介绍可参见维基百科 ...
- 杂乱的code
/*o(n)的堆化方法*/ void myjust(vector<int>& A,int i){ int l=i*2+1; int r=i*2+2; int minn=i; if( ...
- CGIC函数说明
CGIC函数说明 参考cgic函数说明_Embedded Resources Library Online (C)郝博士 cgiFormResultType cgiFormString( char * ...
- ImageNet Classification with Deep Convolutional Neural Network(转)
这篇论文主要讲了CNN的很多技巧,参考这位博主的笔记:http://blog.csdn.net/whiteinblue/article/details/43202399 https://blog.ac ...