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;
    }
  • 相关阅读:
    C#基本数据类型
    ASP.NET MVC 实现二级域名
    asp.net下通过泛解析和伪静态实现二级域名的实现方法
    Web Forms vs Web MVC
    WebForm页面生命周期及asp.net运行机制
    波函数坍缩
    whoami
    wstngfw中使用虚拟IP映射内网IP
    Thread-specific data(TSD)线程私有数据
    Libev库学习
  • 原文地址:https://www.cnblogs.com/leotan0321/p/6081395.html
Copyright © 2011-2022 走看看