从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生。编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr。

有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为配偶,且结为配偶后幸福程度为 ww。

请问这个班级里幸福程度之和最大是多少?

输入格式

第一行三个正整数,nl,nr,mnl,nr,m。

接下来 mm 行,每行三个整数 v,u,wv,u,w 表示第 vv 个男生和第 uu 个女生愿意结为配偶,且幸福程度为 ww。保证 1≤v≤nl1≤v≤nl,1≤u≤nr1≤u≤nr,保证同一对 v,uv,u 不会出现两次。

输出格式

第一行一个整数,表示幸福程度之和的最大值。

接下来一行 nlnl 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生的配偶的编号。如果 vv 号男生没配偶请输出 00。

样例一

input

2 2 3
1 1 100
1 2 1
2 1 1

output

100
1 0

限制与约定

1≤nl,nr≤4001≤nl,nr≤400,1≤m≤1600001≤m≤160000,1≤w≤1091≤w≤109。

时间限制:1s1s

空间限制:256MB

二分图最大权匹配模板题 KM算法

KM算法略神奇的样子……

http://www.cnblogs.com/wenruo/p/5264235.html

↑感觉这里讲得挺清晰

KM算法求的是最大权完备匹配,为了解决两边点数不同的情况,需要虚拟一些点使得两边点数相等

↑但是这种DFS写法被无情卡掉

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#define LL long long
using namespace std;
const LL INF=1LL<<;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void write(LL x){
if(x>)write(x/);
putchar(x%+'');
return;
}
inline LL mini(LL a,LL b){return a<b?a:b;}
inline LL maxi(LL a,LL b){return a>b?a:b;}
int nL,nR,bl,br,m;
int visL[mxn],visR[mxn];
LL exL[mxn],exR[mxn];
int link[mxn];
LL slack[mxn];
int mp[mxn][mxn];
LL ans=;
int a[mxn];
int dtime=;
bool DFS(int u){
visL[u]=dtime;
for(int i=;i<=nR;i++){
if(visR[i]==dtime)continue;
LL d=exL[u]+exR[i]-mp[u][i];
if(!d){
visR[i]=dtime;
if(!link[i] || DFS(link[i])){
link[i]=u;
return ;
}
}
else slack[i]=min(slack[i],d);
}
return ;
}
void KM(){
// memset(link,0,sizeof link);
// memset(exR,0,sizeof exR);
for(int i=;i<=nL;i++){
exL[i]=;
for(int j=;j<=nR;j++){
exL[i]=maxi(exL[i],mp[i][j]);
}
}
for(int i=;i<=nL;i++){
// memset(slack,0x3f,sizeof slack);
for(int j=;j<=nR;j++)slack[j]=INF;
while(){//直到匹配成功为止
dtime++;
// memset(visL,0,sizeof visL);
// memset(visR,0,sizeof visR);
if(DFS(i))break;
LL d=INF;
for(int j=;j<=nR;j++){
if(visR[j]!=dtime)d=mini(d,slack[j]);
}
for(int j=;j<=nL;j++){
if(visL[j]==dtime)exL[j]-=d;
if(visR[j]==dtime)exR[j]+=d;
else slack[j]-=d;
}
}
}
ans=;
nL=bl;nR=br;
for(int i=;i<=nR;i++){
if(mp[link[i]][i]){
a[link[i]]=i;
ans+=mp[link[i]][i];
}
}
printf("%lld\n",ans);
for(int i=;i<=nL;i++){
write(a[i]);
putchar(' ');
}
printf("\n");
return;
}
int main(){
int i,j;
nL=read();
nR=read();
bl=nL;br=nR;
nL=max(nL,nR);
nR=nL;
m=read();
int u,v,w;
for(i=;i<=m;i++){
u=read();v=read();w=read();
mp[u][v]=w;
}
KM();
return ;
}

DFS TLE

于是在status里抄了个BFS的写法。

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void write(LL x){
if(x>)write(x/);
putchar(x%+'');
return;
}
inline int mini(int a,int b){return a<b?a:b;}
inline int maxi(int a,int b){return a>b?a:b;}
int nL,nR,bl,br,m;
int visL[mxn],visR[mxn];
int exL[mxn],exR[mxn];
int link[mxn],pre[mxn],lx[mxn];
int slack[mxn];
int mp[mxn][mxn];
//
LL ans=;
int a[mxn];
int dtime=;
int q[mxn<<],hd,tl;
void Aug(int rt){
if(!rt)return;
link[rt]=pre[rt];
Aug(lx[pre[rt]]);
lx[pre[rt]]=rt;
return;
}
void BFS(int S){
int i,j,tmp;++dtime;
memset(slack,0x3f,sizeof slack);
hd=tl=;q[tl]=S;
while(){
while(hd<=tl){
int u=q[hd];++hd;
visL[u]=dtime;
for(int i=;i<=nR;i++){
if(visR[i]^dtime){
tmp=exL[u]+exR[i]-mp[u][i];
if(!tmp){
visR[i]=dtime;pre[i]=u;
if(!link[i]){
Aug(i);
return;
}
q[++tl]=link[i];
//
}
else if(tmp<slack[i])slack[i]=tmp,pre[i]=u;
}
}
}
tmp=INF;
for(i=;i<=nR;i++)if(visR[i]^dtime)tmp=mini(tmp,slack[i]);
for(i=;i<=nL;i++){
if(visL[i]==dtime)exL[i]-=tmp;
if(visR[i]==dtime)exR[i]+=tmp;
else slack[i]-=tmp;
}
for(i=;i<=nR;i++){
if(visR[i]^dtime && !slack[i]){
visR[i]=dtime;
if(!link[i]){
// link[i]=pre[i];
Aug(i);
return;
}
q[++tl]=link[i];
}
}
}
return;
}
void KM(){
for(int i=;i<=nL;i++){
exL[i]=;
for(int j=;j<=nR;j++)
exL[i]=max(exL[i],mp[i][j]);
}
for(int i=;i<=nL;i++) BFS(i);
ans=;
nL=bl;nR=br;
for(int i=;i<=nR;i++){
if(mp[link[i]][i]){
a[link[i]]=i;
ans+=mp[link[i]][i];
}
}
printf("%lld\n",ans);
for(int i=;i<=nL;i++){
write(a[i]);
putchar(' ');
}
printf("\n");
return;
}
int main(){
int i,j;
nL=read();
nR=read();
bl=nL;br=nR;
nL=max(nL,nR);
nR=nL;
m=read();
int u,v,w;
for(i=;i<=m;i++){
u=read();v=read();w=read();
mp[u][v]=w;
}
KM();
return ;
}

UOJ#80 二分图最大权匹配 [模板题]的更多相关文章

  1. UOJ#80. 二分图最大权匹配 模板

    #80. 二分图最大权匹配 描述 提交 自定义测试 从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr. 有若干个这 ...

  2. uoj#80 二分图最大权匹配

    题意:给定二分图,有边权,求最大边权匹配.边权非负. 解:KM算法求解最大权完备匹配. 完备匹配就是点数少的那一边每个点都有匹配. 为了让完备匹配与最大权匹配等价,我们添加若干条0边使之成为完全二分图 ...

  3. [SDOI2006] 仓库管理员的烦恼 - 二分图最大权匹配

    最小化代价,即最大化"本土"货物的数量 于是就是个二分图最大权匹配裸题 #include <bits/stdc++.h> using namespace std; #d ...

  4. @noi.ac - 507@ 二分图最大权匹配

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一天你学了一个能解决二分图最大权匹配的算法,你决定将这个算法应 ...

  5. HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    ...

  6. [ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)

    奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间 ...

  7. [SDOI2017] 新生舞会 - 二分图最大权匹配,分数规划,二分答案

    有一个二分图,每个部都有 \(n\) 个点,每条边有两个参数 \(a_e, b_e\),求一种匹配,使得 \(\sum a_i / \sum b_i\) 最大 Solution 显然的分数规划,考虑二 ...

  8. [hdu1533]二分图最大权匹配 || 最小费用最大流

    题意:给一个n*m的地图,'m'表示人,'H'表示房子,求所有人都回到房子所走的距离之和的最小值(距离为曼哈顿距离). 思路:比较明显的二分图最大权匹配模型,将每个人向房子连一条边,边权为曼哈顿距离的 ...

  9. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

随机推荐

  1. 在Linux下通过rpm打包发布Java程序

    这个东西涉及的内容较多,根据下面这些文章慢慢学习 一个简单的例子 http://blog.csdn.net/king_on/article/details/7169384 按照文章中的步骤来,打包之后 ...

  2. SVN脱离锁定的几种方法

    SVN经常出现被锁定而无法提交的问题,选择解锁又提示没有文件被锁定,很是头疼.这里整理了一下SVN 被锁定的几种解决方法: 1.出现这个问题后使用“清理”即"Clean up"功能 ...

  3. MyCAT+MySQL 搭建高可用企业级数据库集群——第2章 MyCat入门

    2-1 章节综述 2-2 什么是MyCat 2-3 什么是数据库中间层 2-4 MyCat的主要作用 2-5 MyCat基本元素 2-6 MyCat的安装 2-1 章节综述 1.掌握Mycat的基础概 ...

  4. Mybatis 异常记录(1): Invalid bound statement (not found)

    错误信息: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.pingan.cr ...

  5. Hyperledger04

    代码 'use strict'; var Fabric_Client = require('fabric-client'); var path = require('path'); var util ...

  6. Drools 7.4.1.Final参考手册(六) 用户手册

    用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...

  7. HDU 4587 TWO NODES(割点)(2013 ACM-ICPC南京赛区全国邀请赛)

    Description Suppose that G is an undirected graph, and the value of stab is defined as follows: Amon ...

  8. Alpha阶段展示

    程序员杀产品经理祭天(SacrificePM)团队 1.团队成员简介和个人博客地址 故事 我们队伍的建立过程稍具戏剧性,大家看我们也颇为奇怪,这么一支8人队伍是怎么诞生的呢?其实我们原本分属三组,而第 ...

  9. lintcode-57-三数之和

    57-三数之和 给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组. 注意事项 在三元组(a, b, c),要求a <= b <= ...

  10. Jquery 跨域请求JSON数据问题

    制作网站时,我们有时候为了方便快捷会调用别人写好的API接口,或者是调用一些免费的API接口获得JSON数据.比如天气,农历,网站备案信息查询等. 但是,这些API接口都是别人自己服务器上的,我们要调 ...