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。保证 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
空间限制: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 }