Uva live 4043 Ants( KM+简单的计算几何)

来源:互联网 发布:淘宝网魔豆妈妈 编辑:程序博客网 时间:2024/06/10 02:15

一定要清楚的一个问题,就是:(如图)两条黑色的线的和一定小于蓝色的和,但是平方的和之间就不一定是这个关系了!


代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>using namespace std;const double INF = 0x7fffffff;const double eps = 1e-9;const int N = 110;int n;double w[N][N], lx[N], ly[N];int l[N], r[N];int wx[N], wy[N], bx[N], by[N];bool S[N], T[N];bool eq( double x, double y ) {    return fabs ( x - y ) < eps;}bool match( int i ){    S[i] = true;    for ( int j = 1; j <= n; ++j ) if ( eq( lx[i] + ly[j], w[i][j] ) && !T[j] ) {        T[j] = true;        if ( !l[j] || match(l[j]) ) {            l[j] = i;            //r[i] = j;            return true;        }    }    return false;}void update(){    double a = INF;    for ( int i = 1; i <= n; ++i ) if ( S[i] )         for ( int j = 1; j <= n; ++j ) if ( !T[j] )             a = min( a, lx[i]+ly[j]-w[i][j] );    for ( int i = 1; i <= n; ++i ) {        if ( S[i] ) lx[i] -= a;        if ( T[i] ) ly[i] += a;    }}void KM(){    //memset(l, 0, sizeof(l));    //memset(r, 0, sizeof(r));    for ( int i = 1; i <= n; ++i ) {        l[i] = lx[i] = ly[i] = 0;        for ( int j = 1; j <= n; ++j )             lx[i] = max( lx[i], w[i][j] );    }    for ( int i = 1; i <= n; ++i ) {        for(;;) {            for ( int j = 1; j <= n; ++j ) S[j] = T[j] = 0;            if ( match(i) ) break;             else update();        }    }}int main(){    bool first = false;    while ( scanf("%d", &n) != EOF ) {        if ( first ) printf("\n");        first = true;        for ( int i = 1; i <= n; ++i ) scanf("%d%d", &wx[i], &wy[i]);        for ( int i = 1; i <= n; ++i ) scanf("%d%d", &bx[i], &by[i]);        for ( int i = 1; i <= n; ++i )             for ( int j = 1; j <= n; ++j )                 w[j][i] = -sqrt((double)(wx[i]-bx[j])*(wx[i]-bx[j])+(double)(wy[i]-by[j])*(wy[i]-by[j]));        KM();        for ( int i = 1; i <= n; ++i ) printf("%d\n", l[i]);    }}


原创粉丝点击