zoukankan      html  css  js  c++  java
  • poj3656

    题解:

    二分图最大匹配

    根据三角形不等式

    直接上最大匹配即可

    注意编圈取相反数

    代码:

    #include<iostream>  
    #include<algorithm>  
    #include<cstdio>  
    #include<cstring>  
    #include<cmath>  
    using namespace std;  
    const int N=110;  
    const double INF=0xffffffffffff,eps=1e-6;  
    struct Node{double x,y;}Dot1[N],Dot2[N];  
    double Dist(Node a,Node b)  
    {  
        return -sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));  
    }  
    int n,NX,NY,link[N],visx[N],visy[N];  
    double Map[N][N],lx[N],ly[N],slack[N];  
    int FindPath(int u)  
    {  
        visx[u]=1;  
        for (int i=1;i<=NY;i++)  
         {  
            if (visy[i])continue;  
            double temp=lx[u]+ly[i]-Map[u][i];  
            if (fabs(temp)<=eps)  
             {  
                visy[i]=1;  
                if (link[i]==-1||FindPath(link[i]))  
                 {  
                    link[i]=u;  
                    return 1;  
                 }  
             }  
            else if (slack[i]>temp)slack[i]=temp;
        }  
        return 0;  
    }  
    void KM()  
    {  
        memset(lx,0,sizeof(lx));  
        memset(ly,0,sizeof(ly));  
        memset(link,-1,sizeof(link));  
        for (int i=1;i<=NX;i++)  
         for (int j=1;j<=NY;j++)  
          if (Map[i][j]>lx[i])lx[i]=Map[i][j];  
        for (int i=1;i<=NX;i++)  
         {  
            for (int j=1;j<=NY;j++)slack[j]=INF;  
            while (1)  
             {  
                memset(visx,0,sizeof(visx));  
                memset(visy,0,sizeof(visy));  
                if (FindPath(i))break;  
                double d=INF;  
                for (int j=1;j<=NY;j++)  
                 if (!visy[j]&&d>slack[j])d=slack[j];  
                for (int j=1;j<=NX;j++)  
                 if (visx[j])lx[j]-=d;  
                for (int j=1;j<=NY;j++)  
                 {  
                    if (visy[j])ly[j]+=d;  
                    else slack[j]-=d;  
                 }  
             }  
         }  
    }  
    int main()  
    {  
        while (~scanf("%d",&n))  
         {  
            memset(Map,0,sizeof(Map));  
            for (int i=1;i<=n;i++)scanf("%lf%lf",&Dot1[i].x,&Dot1[i].y);  
            for (int i=1;i<=n;i++)scanf("%lf%lf",&Dot2[i].x,&Dot2[i].y);  
            for (int i=1;i<=n;i++)  
             for (int j=1;j<=n;j++)Map[i][j]=Dist(Dot1[i],Dot2[j]);  
            NX=NY=n;  
            KM();  
            for (int i=1;i<=N;i++)    
             for (int j=1;j<=N;j++)    
              if (link[j]==i)  
               {  
                printf("%d
    ",j);  
                break;  
               }
         }  
        return 0;  
    }  
    

      

  • 相关阅读:
    Atitit. 衡量项目规模 包含的类的数量 .net java类库包含多少类 多少个api方法??
    Drawable 中getIntrinsicWidth
    js播放音乐
    Parcelable和Parcel
    标题栏和状态栏
    android振动效果的实现
    Android位置服务和Google地图API初解
    TranslateAnimation详解
    android真机调试
    常见的Android图标大小
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8311609.html
Copyright © 2011-2022 走看看