POJ3565-Ants-KM变形

时间:2020-04-14
本文章向大家介绍POJ3565-Ants-KM变形,主要包括POJ3565-Ants-KM变形使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意:

给出n个蚂蚁和苹果的坐标,对每个蚂蚁和苹果进行匹配(之间连一条线段),要求:任意两条线段不相交,输出一种方案。

思路:

因为三角形的两边之和大于第三边,

所有他们连线的所有线段和最小的时候线段一定不会相交,

所以这道题目就变成了二分图最小权值匹配,把任意两点间权值即为他们的距离,跑一遍KM即可

注意:

套KM模板的时候,必须从1开始记录,否则不出结果

出来任意一种方案即可,不一定要和样例输出一样

double类型不要弄错

double类型比较的时候最好用<eps,因为精度问题,直接判断等于0可能会出错

AC代码:

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<queue>
  4 #include<cmath>
  5 #include<string.h>
  6 using namespace std;
  7 #define inf 0x3f3f3f3f
  8 typedef long long ll;
  9 const int N=110;
 10 #define inf 0x3f3f3f3f
 11 #define eps 1e-9
 12 
 13 //man x、woman y
 14 int n,match[N];
 15 double love[N][N],exy[N],exx[N],need[N];//***
 16 bool booky[N],bookx[N];
 17 struct node
 18 {
 19     int x,y;
 20 } ant[N],apple[N];
 21 
 22 bool dfs(int woman)
 23 {
 24     booky[woman]=1;
 25     for(int i=1; i<=n; i++)//man
 26     {
 27         if(bookx[i])
 28             continue;
 29         double w=exy[woman]+exx[i]-love[woman][i];//***
 30         if(fabs(w)<=eps )//***
 31             // if(w==0)
 32         {
 33             bookx[i]=1;
 34             if(match[i]==-1||dfs(match[i]))
 35             {
 36                 match[i]=woman;
 37                 return 1;
 38             }
 39         }
 40         else
 41             need[i]=min(need[i],w);
 42     }
 43     return 0;
 44 }
 45 
 46 int KM()
 47 {
 48     for(int i=1; i<=n; i++)
 49     {
 50         exy[i]=inf*(-1.0);//***
 51         for(int j=1; j<=n; j++)
 52             exy[i]=max(exy[i],love[i][j]);
 53     }
 54     for(int i=1; i<=n; i++)
 55     {
 56         fill(need+1,need+n+1,inf);//***
 57         while(1)
 58         {
 59             memset(bookx,0,sizeof bookx);
 60             memset(booky,0,sizeof booky);//放在这里清空,清空和break不能掉头否则TLE
 61             if(dfs(i))
 62                 break;
 63             double minn=inf;//***
 64             for(int j=1; j<=n; j++)
 65             {
 66                 if(bookx[j]==0)
 67                     minn=min(minn,need[j]);
 68             }
 69             for(int j=1; j<=n; j++)
 70             {
 71                 if(booky[j])
 72                     exy[j]-=minn;
 73                 if(bookx[j])
 74                     exx[j]+=minn;
 75                 else
 76                     need[j]-=minn;
 77             }
 78         }
 79     }
 80 //    int sum=0;
 81 //    for(int i=0; i<n; i++)
 82 //        sum+=love[match[i]][i];
 83 //    return sum;
 84 }
 85 
 86 int main()
 87 {
 88     while(~scanf("%d",&n))
 89     {
 90         memset(match,-1,sizeof(match));
 91         memset(exx,0,sizeof exx);
 92         memset(exy,0,sizeof exy);
 93         for(int i=1; i<=n; i++)
 94             scanf("%d %d",&ant[i].x,&ant[i].y);
 95         for(int i=1; i<=n; i++)
 96             scanf("%d %d",&apple[i].x,&apple[i].y);
 97         for(int i=1; i<=n; i++)
 98         {
 99             for(int j=1; j<=n; j++)
100 
101                 love[j][i]=(-1.0)*sqrt((ant[i].x-apple[j].x)*(ant[i].x-apple[j].x)+(ant[i].y-apple[j].y)*(ant[i].y-apple[j].y));
102         }
103         KM();
104         for(int i=1; i<=n; i++)
105             printf("%d\n",match[i]);
106     }
107     return 0;
108 }
View Code

原文地址:https://www.cnblogs.com/OFSHK/p/12697586.html