标签:util style func errno stream || ring limits 1.0
[题目链接]
http://poj.org/problem?id=3565
[算法]
KM算法求最小匹配
[代码]
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 110 const double INF = 1e12; const double eps = 1e-5; int i,j,n; pair<double,double> a[MAXN],b[MAXN]; double w[MAXN][MAXN]; double la[MAXN],lb[MAXN]; double delta; int ans[MAXN],match[MAXN]; bool visiteda[MAXN],visitedb[MAXN]; inline double dist(pair<double,double> a,pair<double,double> b) { return 1.0 * sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second)); } inline bool dfs(int u) { int v; visiteda[u] = true; for (v = 1; v <= n; v++) { if (!visitedb[v]) { if (fabs(la[u] + lb[v] - w[u][v]) < eps) { visitedb[v] = true; if (!match[v] || dfs(match[v])) { match[v] = u; return true; } } } } return false; } inline void KM() { int i,j,k; memset(match,0,sizeof(match)); for (i = 1; i <= n; i++) { la[i] = -INF; lb[i] = 0; for (j = 1; j <= n; j++) la[i] = max(la[i],w[i][j]); } for (i = 1; i <= n; i++) { while (true) { delta = INF; for (j = 1; j <= n; j++) visiteda[j] = visitedb[j] = false; if (dfs(i)) break; for (j = 1; j <= n; j++) { if (visiteda[j]) { for (k = 1; k <= n; k++) { if (!visitedb[k]) delta = min(delta,la[j] + lb[k] - w[j][k]); } } } for (j = 1; j <= n; j++) { if (visiteda[j]) la[j] -= delta; if (visitedb[j]) lb[j] += delta; } } } } int main() { scanf("%d",&n); for (i = 1; i <= n; i++) scanf("%lf%lf",&a[i].first,&a[i].second); for (i = 1; i <= n; i++) scanf("%lf%lf",&b[i].first,&b[i].second); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { w[i][j] = -dist(a[i],b[j]); } } KM(); for (i = 1; i <= n; i++) ans[match[i]] = i; for (i = 1; i <= n; i++) printf("%d\n",ans[i]); return 0; }
标签:util style func errno stream || ring limits 1.0
原文地址:https://www.cnblogs.com/evenbao/p/9414290.html