UOJ #78 二分图最大匹配
#78. 二分图最大匹配
从前一个和谐的班级,有 nl 个是男生,有 nr 个是女生。编号分别为 1,…,nl 和 1,…,nr。
有若干个这样的条件:第 v 个男生和第 u 个女生愿意结为配偶。
请问这个班级里最多产生多少对配偶?
输入格式
第一行三个正整数,nl,nr,m。
接下来 m 行,每行两个整数 v,u 表示第 v 个男生和第 u 个女生愿意结为配偶。保证 1≤v≤nl,1≤u≤nr,保证同一个条件不会出现两次。
输出格式
第一行一个整数,表示最多产生多少对配偶。
接下来一行 nl 个整数,描述一组最优方案。第 v 个整数表示 v 号男生的配偶的编号。如果 v 号男生没配偶请输出 0。
样例一
input
2 2 3
1 1
1 2
2 1
output
2
2 1
explanation
1 号男生跟 2 号女生幸福地生活在了一起~
2 号男生跟 1 号女生幸福地生活在了一起~
样例二
input
2 2 2
1 1
2 1
output
1
1 0
explanation
班上一个女神一个女汉子,两个男生都去追女神。一种最优方案是:
1 号男生跟 1 号女生幸福地生活在了一起~
2 号男生孤独终生。= =||
限制与约定
1≤nl,nr≤500,1≤m≤250000。
时间限制:1s
空间限制:256MB
题解:先写网络流,跑的还挺快。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
struct isap{
struct ted{int x,y,w;ted*nxt,*re;}adj[maxm],*fch[maxn],*cur[maxn],*ms;
int gap[maxn],d[maxn],ret[maxn],n,S,T;
void init(int n){memset(d,-,sizeof(d));ms=adj;this->n=n;return;}
void add(int x,int y,int w){
*ms=(ted){x,y,w,fch[x],ms+};fch[x]=ms++;
*ms=(ted){y,x,,fch[y],ms-};fch[y]=ms++;
return;
}
void bfs(){
queue<int>Q;Q.push(T);d[T]=;
while(!Q.empty()){
int x=Q.front();Q.pop();
for(ted*e=fch[x];e;e=e->nxt){
int v=e->y;if(d[v]<)d[v]=d[x]+,Q.push(v);
}
}return;
}
int mxflow(int S,int T){
this->S=S;this->T=T;bfs();int flow=,k=S;ted*e;
for(int i=;i<=n;i++)gap[d[i]]++,cur[i]=fch[i];
while(d[S]<n){
if(k==T){int mi=inf,p;
for(int i=S;i!=T;i=cur[i]->y)if(cur[i]->w<mi)mi=cur[i]->w,p=i;
for(int i=S;i!=T;i=cur[i]->y)cur[i]->w-=mi,cur[i]->re->w+=mi;flow+=mi;k=p;
}for(e=cur[k];e;e=e->nxt)if(e->w&&d[k]==d[e->y]+)break;
if(e){cur[k]=e;k=e->y;ret[e->y]=e->x;}
else{if(--gap[d[k]]==)break;cur[k]=fch[k];int mi=n;
for(ted*e=fch[k];e;e=e->nxt)if(e->w&&d[e->y]<mi)mi=d[e->y];
d[k]=mi+;gap[d[k]]++;if(k!=S)k=ret[k];
}
}return flow;
}
int print(int x){
for(ted*e=fch[x];e;e=e->nxt)if(!e->w&&!((e-adj)&))return e->y;return ;
}
}sol;
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')sig=-;ch=getchar();}
while(isdigit(ch))x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
int n1,n2,m;
void init(){
n1=read();n2=read();m=read();sol.init(n1+n2+);int x,y,w,S=n1+n2+,T=n1+n2+;
for(int i=;i<=n1;i++)sol.add(S,i,);
for(int i=n1+;i<S;i++)sol.add(i,T,);
for(int i=;i<=m;i++)x=read(),y=read()+n1,sol.add(x,y,);
write(sol.mxflow(S,T));ENT;int tmp;
for(int i=;i<=n1;i++)write((tmp=sol.print(i))?tmp-n1:),PAU;
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}
UOJ #78 二分图最大匹配的更多相关文章
- 二分图最大匹配|UOJ#78|匈牙利算法|边表|Elena
#78. 二分图最大匹配 从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr. 有若干个这样的条件:第 vv 个男生 ...
- POJ 2226二分图最大匹配
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...
- POJ2239 Selecting Courses(二分图最大匹配)
题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...
- poj 2239 二分图最大匹配,基础题
1.poj 2239 Selecting Courses 二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...
- UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法
二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...
- 二分图最大匹配的König定理及其证明
二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有. 以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上 ...
- POJ3057 Evacuation(二分图最大匹配)
人作X部:把门按时间拆点,作Y部:如果某人能在某个时间到达某门则连边.就是个二分图最大匹配. 时间可以二分枚举,或者直接从1枚举时间然后加新边在原来的基础上进行增广. 谨记:时间是个不可忽视的维度. ...
- ZOJ1654 Place the Robots(二分图最大匹配)
最大匹配也叫最大边独立集,就是无向图中能取出两两不相邻的边的最大集合. 二分图最大匹配可以用最大流来解. 如果题目没有墙,那就是一道经典的二分图最大匹配问题: 把地图上的行和列分别作为点的X部和Y部, ...
- HDU:过山车(二分图最大匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2063 题意:有m个男,n个女,和 k 条边,求有多少对男女可以搭配. 思路:裸的二分图最大匹配,匈牙利算法. 枚 ...
随机推荐
- rpc远程过程协议调用
在linux 5.X以及下的版本你可以通过service portmap status命令查看rpc是否启动.如果提示running,表示正在运行:如果提示stop就是关闭了.如果没有安装,则通过安装 ...
- Amoeba for MySQL 非常好用的mysql集群软件
http://docs.hexnova.com/amoeba/ Amoeba for MySQL致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当query 路由功能,专 ...
- 改写URL的查询字符串QUERY_STRING(转)
查询字符串是指URL请求中“问号”后面的部分.比如,http://www.nowamagic.net/?foo=bar中粗体部分就是查询字符串,其中变量名是foo,值是bar. 1. 利用QSA转换查 ...
- SPOJ 181 - Scuba diver 二维背包
潜水员要潜水,给出n个气缸(1<=n<=1000),每个气缸中有氧气量为ti,氮气量为ai,气缸重量为wi(1<=ti<=21,1<=ai<=79,1<=wi ...
- 将sql数据库逆向生成PDM模型
由于接手的一个项目是公司前期外包出去的,所以到手的只有繁杂的代码,和数据库文件.由于是个新手,我需要一个数据字典来帮助我完成一些东西,所以我就想到从sql数据库转换出一个pdm模型的数据字典. 第一步 ...
- Linq101-Set
using System; using System.Collections.Generic; using System.Linq; namespace Linq101 { class Set { / ...
- asp.net中Page.ClientScript.RegisterStartupScript用法小结(转)
//ASP.NET后台页面跳转 Page.ClientScript.RegisterStartupScript(Page.GetType(), "", "<scri ...
- 关于android MTK相机L版本,切换屏幕比例后,分辨率随之改变,但重新进入相机后原有分辨率不再生效问题
BUG详细:比如4:3的时候是200W,切成全屏变400W,重新切回4:3为300W,退出相机后,重新进入又变成200W. 原因分析:这个版本的设计如此,当你点选屏幕比例的时候,程序设计是把这个比例值 ...
- centos5.2 x86 安装 oracle 11g2r 日志
一.安装centos 二.安装ora所需的库 三.修改centos内核 四.建用户组和目录结构等 五.安装ora11g2r 六.安装sqlplus的翻页程序和help补丁 七.自启动脚本 八.常用命令 ...
- 想加入一行代码吗?使用<code>标签
在介绍语言技术的网站中,避免不了在网页中显示一些计算机专业的编程代码,当代码为一行代码时,你就可以使用<code>标签了,如下面例子: <code>var i=i+300;&l ...