• POJ 3565 Ants (最小权匹配)


    题意

    给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案。

    思路

    一开始没想到怎么用最小权匹配……后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)……还是too young too simple……没有融会贯通……

    代码

      [cpp] #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <algorithm> #include <string> #include <cstring> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, m) for (int i = begin; i < begin+m; i ++) using namespace std; const int MAXV = 205; //X or Y点集大小 const int oo = 0x3fffffff; const double eps = 1e-8; template <class weight_type> struct MaximalMatchingOfWeightedBipartiteGraph{ weight_type w[MAXV][MAXV]; //权值 int sv, tv; //Perfect Matching, sv should equal to tv bool S[MAXV], T[MAXV]; weight_type lx[MAXV], ly[MAXV]; //X、Y点集可行顶标 int left[MAXV]; weight_type slack[MAXV]; void init(int v){ sv = tv = v; MEM(w, 0); } void add_uedge(int u, int v, weight_type _w){ w[u][v] = _w; } bool cross_path(int u){ S[u] = true; for (int v = 1; v <= tv; v ++){ if(T[v]) continue; weight_type t = lx[u] + ly[v] - w[u][v]; if (t < eps){ T[v] = true; if (left[v] == 0 || cross_path(left[v])){ left[v] = u; return true; } } else{ slack[v] = min(slack[v], t); } } return false; } weight_type solve(){ //Init MEM(left, 0); for (int i = 1; i <= sv; i ++){ lx[i] = 0; ly[i] = 0; for (int j = 1; j <= tv; j ++) lx[i] = max(lx[i], w[i][j]); } //Main for (int i = 1; i <= sv; i ++){ for (int j = 1; j <= tv; j ++) slack[j] = oo; while(1){ MEM(S, false); MEM(T, false); if (cross_path(i)){ break; } else{ weight_type d = oo; for (int j = 1; j <= tv; j ++) if (!T[j]) d = min(d, slack[j]); for (int j = 1; j <= sv; j ++) if (S[j]) lx[j] -= d; for (int j = 1; j <= tv; j ++){ if (T[j]) ly[j] += d; else slack[j] -= d; //匈牙利树中T集点ly不变,S集点lx减小,更新slack值 } } } } weight_type res = 0; for(int i = 1; i <= sv; i ++) res += lx[i]; for(int i = 1; i <= tv; i ++) res += ly[i]; return res; } }; MaximalMatchingOfWeightedBipartiteGraph <double> km; struct Point{ double x, y; }p[MAXV]; double dist(int i, int j){ return sqrt((p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y)); } int main(){ //freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); int n; while(scanf("%d", &n) != EOF){ REP(i, 1, n){ scanf("%lf %lf", &p[i+n].x, &p[i+n].y); } REP(i, 1, n){ scanf("%lf %lf", &p[i].x, &p[i].y); } km.init(n); REP(i, 1, n){ REP(j, 1, n){ km.add_uedge(i, j, -dist(i, j+n)); } } //printf("%f ", -km.solve()); km.solve(); REP(i, 1, n){ printf("%d ", km.left[i]); } } return 0; } [/cpp]
  • 相关阅读:
    信息产品是信息化理念的凝缩的精华
    自然科学技术表面上是反应人与自然的关系,更深层还是人与人之间的关系
    思与在,为何没有行
    haproxysocket 参数记录
    zabbix 监控 haproxy 记录
    Centos6.5安装OpenLDAP
    ansible mysql模块的使用今年
    haproxy 官方文档查看
    centos 7 部署 mysql 报错记录
    ansible playbook学习
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114300.html
Copyright © 2020-2023  润新知