HDU - 2255 奔小康赚大钱 KM算法 模板题
题意:
分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多。
思路:
KM算法裸题。上模板
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <map> #include <set> #include <queue> #include <list> #include <cstdlib> #include <iterator> #include <cmath> #include <iomanip> #include <bitset> #include <cctype> using namespace std; //#pragma GCC optimize(3) // #pragma comment(linker, "/STACK:102400000,102400000") //c++ #define lson (l, mid, rt << 1) #define rson (mid + 1, r, rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll> pll; typedef pair<int, int> pii; typedef pair<int, pii> p3; //priority_queue<int> q;//这是一个大根堆q //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second //#define endl '\n' #define OKC \ ios::sync_with_stdio(false); \ cin.tie(0) #define FT(A, B, C) for (int A = B; A <= C; ++A) //用来压行 #define REP(i, j, k) for (int i = j; i < k; ++i) //priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFFLL; //2147483647 const ll nmos = 0x80000000LL; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3fLL; //18 const double PI = acos(-1.0); template <typename T> inline T read(T &x) { x = 0; int f = 0; char ch = getchar(); while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x = f ? -x : x; } // #define _DEBUG; //*// #ifdef _DEBUG freopen("input", "r", stdin); // freopen("output.txt", "w", stdout); #endif /*-----------------------show time----------------------*/ const int maxn = 309; int mp[maxn][maxn]; int n, m; int wx[maxn], wy[maxn]; int linkx[maxn], linky[maxn]; bool visx[maxn], visy[maxn]; int minz; bool dfs(int s) { visx[s] = true; for (int i = 1; i <= n; i++) { if (!visy[i]) { int t = wx[s] + wy[i] - mp[s][i]; if (t == 0) { visy[i] = true; if (linky[i] == 0 || dfs(linky[i])) { linkx[s] = i; linky[i] = s; return true; } } else if (t > 0) { if (t < minz) minz = t; } } } return false; } void km() { for (int i = 1; i <= n; i++) linkx[i] = linky[i] = 0; for (int i = 1; i <= n; i++) { wx[i] = -inf; for (int j = 1; j <= n; j++) { wx[i] = max(wx[i], mp[i][j]); } wy[i] = 0; } for (int i = 1; i <= n; i++) { while (true) { for (int j = 1; j <= n; j++) { visx[j] = visy[j] = 0; } minz = inf; if (dfs(i)) break; for (int j = 1; j <= n; j++) { if (visx[j]) wx[j] -= minz; if (visy[j]) wy[j] += minz; } } } } int main() { while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &mp[i][j]); } } km(); ll ans = 0; for (int i = 1; i <= n; i++) { ans += mp[i][linkx[i]]; } printf("%lld\n", ans); } return 0; }
skr