zoukankan      html  css  js  c++  java
  • 【vijos】【二分图带权匹配】拯救世界-星际大战

    描述

    外星人逐渐逼近,为了保护地球,现在决定直接在外空进行战斗。
    现在我们有N个导弹。需要在最短的时间内,用这N个导弹摧毁敌方n个目标(1个导弹只能摧毁1个目标)。N个导弹和目标的位置不一定相同,但是给每个导弹确定目标是一件很麻烦的事情。请你编程帮助给每个导弹确定目标,使每个导弹到其目标的距离之和最小。

    格式

    输入格式

    第一行输入N(N<=20)
    接下来N行每行包含一个坐标(x,y),表示一个导弹,-10000

    输出格式

    每个导弹到其目标距离之和的最小值。结果保留3位小数。

    代码

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define INF 0x3f
    #define maxn 25
    using namespace std;
    
    struct Po{
        int x,y;
        Po(int x=0,int y=0){
            this->x=x; this->y=y;
        }
    };
    
    int nx,ny,linky[maxn];
    double lack,w[maxn][maxn],lx[maxn],ly[maxn];
    bool visx[maxn],visy[maxn];
    
    int n;
    Po mi[maxn],tar[maxn];
    
    double dist(Po x,Po y){
        return sqrt(pow(x.x-y.x,2.0)+pow(x.y-y.y,2.0));
    }
    
    bool find(int x){
        visx[x]=true;
        for(int i=1;i<=ny;i++){
            if(visy[i]) continue;
            double t=lx[x]+ly[i]-w[x][i];
            if(t<1e-5){
                visy[i]=true;
                if(linky[i]==-1||find(linky[i])){
                    linky[i]=x;
                    return true;
                }
    
            }else if(t<lack-1e-5) lack=t;
    
        }
        return false;
    }
    
    double KM(){
        memset(linky,-1,sizeof(linky));
        for(int i=1;i<=ny;i++) ly[i]=0.000;
        for(int i=1;i<=nx;i++){
            lx[i]=INF;
            for(int j=1;j<=ny;j++)
                if(w[i][j]-1e-5>lx[i]) lx[i]=w[i][j];
        }
    
        for(int x=1;x<=nx;x++){
            while(true){
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                lack=INF;
                if(find(x)) break;
                for(int i=1;i<=ny;i++){
                    if(visx[i]) lx[i]-=lack;
                    if(visy[i]) ly[i]+=lack;
                }
            }
        }
        double ans=0.000;
        for(int i=1;i<=ny;i++)
            ans-=w[linky[i]][i];
        return ans;
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        scanf("%d",&n); nx=ny=n;
        for(int i=1;i<=n;i++) scanf("%d%d",&mi[i].x,&mi[i].y);
        for(int i=1;i<=n;i++) scanf("%d%d",&tar[i].x,&tar[i].y);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                w[i][j]=-dist(mi[i],tar[j]);
        printf("%.3f",KM());
        return 0;
    }
  • 相关阅读:
    android之ConnectivityManager简介,网络连接状态
    SPOJ SUBLEX 7258. Lexicographical Substring Search
    poj 2417 Discrete Logging(A^x=B(mod c),普通baby_step)
    设计模式汇总
    微信公众平台预研小结
    Android开发之Handler的用法(源码分享)
    通过ccb(CocosBuilder)文件生成cocos2dx代码
    图像处理之错切变换
    combobox自己主动提示组件加入无选中项清空功能
    php 二维数组传递给 js 问题解决记录
  • 原文地址:https://www.cnblogs.com/leotan0321/p/6081395.html
Copyright © 2011-2022 走看看