最优匹配
最小权匹配:
#include <iostream> #include <cstdio> #include <cstring> usingnamespace std; constint N =210; constint M =30100; constint inf =0x1fffffff; int n, m, tot, lx[N], ly[N], match[N], h[N], v[M], w[M], nxt[M]; bool visx[N], visy[N]; int lack; void add(int a, int b, int c) { v[tot] = b; w[tot] = c; nxt[tot] = h[a]; h[a] = tot++; } bool find(int u) { int i, t; visx[u] =true; for(i = h[u]; i !=-1; i = nxt[i]) if(!visy[v[i]]) { t = w[i] - lx[u] - ly[v[i]]; if(t ==0) { visy[v[i]] =true; if(match[v[i]]==-1|| find(match[v[i]])) { match[v[i]] = u; returntrue; } } elseif(t >0) lack = min(lack, t); } returnfalse; } int main() { int t, a, b, c, i, j, ans; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); tot =0; memset(h, -1, sizeof(h)); for(i =0; i < m; i++) { scanf("%d%d%d", &a, &b, &c); add(a, b, c); } for(i =1; i <= n; i++) { lx[i] = inf; ly[i] =0; for(j = h[i]; j !=-1; j = nxt[j]) lx[i] = min(lx[i], w[j]); } memset(match, -1, sizeof(match)); for(i =1; i <= n; i++) { memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); lack = inf; while(!find(i)) { for(j =1; j <= n; j++) { if(visx[j]) lx[j] += lack; if(visy[j]) ly[j] -= lack; } memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); } } ans =0; for(i =1; i <= n; i++) ans = ans + lx[i] + ly[i]; printf("%d\n", ans); } return 0; }
最大权匹配:
#include <iostream> #include <cstdio> #include <cstring> usingnamespace std; constint N =310; constint inf =0x1fffffff; int n, lx[N], ly[N], match[N], w[N][N]; bool visx[N], visy[N]; int lack; int getNum() { char c; int ans =0; c = getchar(); while(c<'0'|| c>'9') c = getchar(); while(c>='0'&& c<='9') { ans = ans*10+c-'0'; c = getchar(); } return ans; } bool find(int u) { int i, t; visx[u] =true; for(i =1; i <= n; i++) if(!visy[i]) { t = lx[u] + ly[i] - w[u][i]; if(t ==0) { visy[i] =true; if(match[i]==-1|| find(match[i])) { match[i] = u; returntrue; } } elseif(t >0) lack = min(lack, t); } returnfalse; } int main() { int i, j, ans; while(scanf("%d", &n) != EOF) { for(i =1; i <= n; i++) { lx[i] = ly[i] =0; for(j =1; j <= n; j++) { w[i][j] = getNum(); lx[i] = max(lx[i], w[i][j]); } } memset(match, -1, sizeof(match)); for(i =1; i <= n; i++) { memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); lack = inf; while(!find(i)) { for(j =1; j <= n; j++) { if(visx[j]) lx[j] -= lack; if(visy[j]) ly[j] += lack; } memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); } } ans =0; for(i =1; i <= n; i++) ans = ans + lx[i] + ly[i]; printf("%d\n", ans); } return0; }