POJ3565-Ants-KM变形
Posted ofshk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",match[i]);
106 }
107 return 0;
108 }
以上是关于POJ3565-Ants-KM变形的主要内容,如果未能解决你的问题,请参考以下文章