POJ 3565 Ants(二分图最小权完备匹配)
来源:互联网 发布:淘宝虚拟物品货源 编辑:程序博客网 时间:2024/06/07 10:19
题意:给定平面上同样多的黑点和白点,要求输出一种方案使得所有匹配的点的连线两两不相交。
思路:构造一个二分图,黑点白点之间的边的权值为两点的欧几里得距离,那么问题就转化为了求二分图的最小权匹配。这是因为如果最小权匹配有两条线段相交,那么一定可以转化为两条不相交且总长度更短的两条线段,这与最小权矛盾,所以可以证明最小权匹配中没有相交的线段。
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-4#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 110;const double INF = 1e17;int n, N, M;double g[MAXN][MAXN], lx[MAXN], ly[MAXN];int linky[MAXN];double slack[MAXN];bool visx[MAXN], visy[MAXN];bool dfs(int x){ int y; visx[x] = true; for(y = 0; y < N; y++) { if(visy[y]) continue; double t = lx[x] + ly[y] - g[x][y]; if(fabs(t) < eps) { visy[y] = true; if(linky[y]==-1 || dfs(linky[y])) { linky[y] = x; return true; } } else { slack[y] = min(slack[y], t); } } return false;}int KM(){ double res = 0; memset(linky, -1, sizeof(linky)); for(int i = 0; i < N; i++) ly[i] = 0; for(int i = 0; i < M; i++) { lx[i] = -INF; for(int j = 0; j < N; j++) { lx[i] = max(lx[i], g[i][j]); } } int x; for(x = 0; x < M; x++) { for(int i = 0; i < N; i++) slack[i] = INF; while(true) { memset(visx, 0, sizeof(visx)); memset(visy, 0, sizeof(visy)); if(dfs(x)) break; double min_slack = INF; for(int i = 0; i < N; i++) { if(!visy[i]) min_slack = min(min_slack, slack[i]); } for(int i = 0; i < M; i++) { if(visx[i]) lx[i] -= min_slack; } for(int i = 0; i < N; i++) { if(visy[i]) ly[i] += min_slack; } } } for(int i = 0; i < N; i++) if(linky[i] != -1) res += g[linky[i]][i]; return res;}struct Point{ double x, y;} ant[MAXN], apple[MAXN];int main(){ //freopen("input.txt", "r", stdin);while(cin >> n) { N = M = n; for(int i = 0; i < n; i++) scanf("%lf%lf", &ant[i].x, &ant[i].y); for(int i = 0; i < n; i++) scanf("%lf%lf", &apple[i].x, &apple[i].y); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) g[j][i] = -sqrt((ant[i].x-apple[j].x)*(ant[i].x-apple[j].x) + (ant[i].y-apple[j].y)*(ant[i].y-apple[j].y)); } KM(); for(int i = 0; i < n; i++) printf("%d\n", linky[i]+1);} return 0;}
0 0
- POJ 3565 Ants(二分图最小权完备匹配)
- LA4043 - Ants(二分图完备最佳匹配KM)
- Ants (poj 3565 最小权匹配)
- 二分图完备匹配(最小费用 || KM) poj 2195 GoingHome
- poj 3565 Ants 最小权匹配
- POJ 3565 Ants (最小权完美匹配 KM算法)
- POJ 3545 Ants(最佳二分图匹配)
- HDU 3488--Tour(二分图最小完备匹配,KM算法)
- [省选前题目整理][LA 4043]Ants(二分图最小权匹配)
- hdu 3488 Tour(二分匹配 最小权完备匹配 km算法)
- 二分图最佳匹配 KM算法 Hdu2255奔小康赚大钱 + Poj 3565 Ants
- POJ 3565 Ants(匹配? 计算几何!)
- hdu 1533 二分图的完备匹配(KM算法)
- HDU3488 Tour(二分图最小完备匹配,KM算法,转化思想)
- 带权的完备二分匹配问题
- 信与信封 (二分图完备匹配)
- hdu 2255 二分图的完备匹配
- poj1469 二分图的完备匹配
- C++ 拷贝构造函数 赋值构造函数
- windows下MemCached的安装
- template关键字
- POJ NO.1182 食物链(并查集,带权并查集最优解,没有之一)
- YTU 2432: C++习题 对象数组输入与输出
- POJ 3565 Ants(二分图最小权完备匹配)
- poj 1324(BFS+状态压缩)
- Android Studio如何删除module
- 【LeetCode OJ 14】Longest Common Prefix
- 枚举类型模拟
- 学习redis基础命令网站
- Swift中定义protocol,定义optional方法
- Swift开发 底部对话框UIActionSheet
- Explicit关键字