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;  
    }  
    

      

  • 相关阅读:
    {转}每次从vss获取文件都是只读
    點擊按鈕后彈出新頁面導致原頁面CSS失效
    Mschat控件示例升级错误处理方法
    一个简单的使用EVP框架的加密过程 aes 128 ecb
    centos7的syslog知识点
    pam模块使用syslog日志调试
    Linux系统上的popen()库函数
    linux C语言 用openssl进行签名验签 --- 亲测2 sha256 sha512
    linux C语言 用openssl进行签名验签 --- 亲测 sha256 sha512
    k8s简介
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8311609.html
Copyright © 2011-2022 走看看