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

Posted 嘒彼小星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ#80. 二分图最大权匹配 模板相关的知识,希望对你有一定的参考价值。

#80. 二分图最大权匹配

从前一个和谐的班级,有 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。保证 1vnl1≤v≤nl,1unr1≤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

限制与约定

1nl,nr4001≤nl,nr≤400,1m1600001≤m≤160000,1w1091≤w≤109。

时间限制1s1s

空间限制256MB256MB

下载

样例数据下载

 

 

http://blog.csdn.net/c20180630/article/details/71080521这篇讲的不错

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #include <map>
 9 #include <string> 
10 #include <cmath> 
11 #define min(a, b) ((a) < (b) ? (a) : (b))
12 #define max(a, b) ((a) > (b) ? (a) : (b))
13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
14 template<class T>
15 inline void swap(T &a, T &b)
16 {
17     T tmp = a;a = b;b = tmp;
18 }
19 inline void read(long long &x)
20 {
21     x = 0;char ch = getchar(), c = ch;
22     while(ch < 0 || ch > 9) c = ch, ch = getchar();
23     while(ch <= 9 && ch >= 0) x = x * 10 + ch - 0, ch = getchar();
24     if(c == -) x = -x;
25 }
26 
27 const long long INF = 0x3f3f3f3f3f3f3f3f;
28 const long long MAXN = 4000 + 10;
29 
30 long long g[MAXN][MAXN], n1, n2, m, tmp1, tmp2, lab1[MAXN], lab2[MAXN], lk1[MAXN], lk2[MAXN], pre[MAXN], sla[MAXN], vis[MAXN];
31 void fac(long long x)
32 {
33     memset(vis, 0, sizeof(vis)), memset(pre, 0, sizeof(pre)), memset(sla, 0x7f, sizeof(sla)), vis[0] = 1;
34     long long y;
35     do
36     {
37         y = 0;
38         for(long long i = 1;i <= n2;++ i)
39         {
40             if(vis[i]) continue;
41             if(lab1[x] + lab2[i] - g[x][i] < sla[i]) sla[i] = lab1[x] + lab2[i] - g[x][i], pre[i] = x;
42             if(sla[i] < sla[y]) y = i;
43         }
44         long long d = sla[y];
45         for(long long i = 1;i <= n1;++ i) if(vis[lk1[i]]) lab1[i] -= d;
46         for(long long i = 1;i <= n2;++ i) if(vis[i]) lab2[i] += d; else sla[i] -= d;
47         vis[y] = 1; 
48     }while(x = lk2[y]);
49     for(;y;swap(y, lk1[lk2[y] = pre[y]]));
50 }
51 long long KM()
52 {
53     for(long long i = 1;i <= n1;++ i) fac(i);
54     long long ans = 0;
55     for(long long i = 1;i <= n1;++ i) ans += g[i][lk1[i]];
56     return ans;
57 }
58 int main()
59 {
60     read(n1), read(n2), n2 = max(n2, n1), read(m);
61     for(long long i = 1;i <= m;++ i)read(tmp1), read(tmp2), read(g[tmp1][tmp2]), lab1[tmp1] = max(g[tmp1][tmp2], lab1[tmp1]);
62     printf("%lld\n", KM());
63     for(long long i = 1;i <= n1;++ i) printf("%lld ", g[i][lk1[i]] ? lk1[i] : 0);
64     return 0;
65 }
UPJ#80

 

以上是关于UOJ#80. 二分图最大权匹配 模板的主要内容,如果未能解决你的问题,请参考以下文章

uoj#80 二分图最大权匹配

UOJ 80 二分图最大权匹配

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

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

二分图 模板

[kuangbin带你飞]专题十 匹配问题 一般图匹配