首页 > 其他 > 详细

poj 3565 uva 1411 Ants KM算法求最小权

时间:2014-03-02 19:04:26      阅读:350      评论:0      收藏:0      [点我收藏+]

  由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了……

  有两种事物,不难想到用二分图。这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案。为啥呢?因为如果有四个点,a,b,c,d Abcd交叉,acbd不交叉,那么acbd的长度和一定小于abcd的长度和,可以画一个图很容易就证出来。所以,如果所有的边都不交叉,又因为有解,那么最小的权值和就是解了。附图一枚,自己画的,比较简陋,凑活着看吧……

bubuko.com,布布扣

  KM算法求最佳完美匹配最小权值和,可以直接把所有的权值转成负值,在求最大权值和,但是这种方法我觉得有些不对劲,但是不知道在哪里= =,上网一查,才发现这种方法只能用于xy数量相同的时候,正统做法应该是用一个很大的数减去每个权值,再求最大权值和。PS:我用的是取反的方法……

 

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #define N 110
 6 struct sss
 7 {
 8     int x,y;
 9 }white[N],black[N];
10 int n,vx[N],vy[N],fa[N];
11 double w[N][N],px[N],py[N],str[N];
12 double dis(int i,int j)
13 {
14     return sqrt((double)(black[i].x-white[j].x)*(black[i].x-white[j].x)+(double)(black[i].y-white[j].y)*(black[i].y-white[j].y));
15 }
16 int find(int now)
17 {
18     int i,j,k;
19     if (now==0)
20       return 1;
21     vx[now]=1;
22     for (i=1;i<=n;i++)
23     {
24       if (!vy[i]&&fabs(px[now]+py[i]-w[now][i])<0.00001)
25       {
26           vy[i]=1;
27           if (fa[i]==0||find(fa[i]))
28           {
29               fa[i]=now;
30               return 1;
31           }
32       }
33       else
34         if (str[i]>px[now]+py[i]-w[now][i])
35           str[i]=px[now]+py[i]-w[now][i];
36     }
37     return 0;
38 }
39 void KM()
40 {
41     int i,j,k,x,y,z;
42     double na;
43     memset(fa,0,sizeof(fa));
44     for (i=1;i<=n;i++)
45     {
46         memset(str,0x7f,sizeof(str));
47         while (1)
48         {
49             memset(vx,0,sizeof(vx));
50             memset(vy,0,sizeof(vy));
51             if (find(i))
52               break;
53             na=0x7f;
54             for (j=1;j<=n;j++)
55               if (!vy[j]&&na>str[j])
56                 na=str[j];
57             for (j=1;j<=n;j++)
58             {
59                 if (vx[j])
60                   px[j]-=na;
61                 if (vy[j])
62                   py[j]+=na;
63                 else
64                   str[j]-=na;
65             }
66         }
67     }
68 }
69 int main()
70 {
71     int i,j,k,x,y,z;
72     z=0;
73     while(scanf("%d",&n)!=EOF)
74     {
75         if (z)
76           printf("\n");
77         else
78           z=1;
79         for (i=1;i<=n;i++)
80           px[i]=-100000;
81         memset(py,0,sizeof(py));
82         for (i=1;i<=n;i++)
83           scanf("%d%d",&white[i].x,&white[i].y);
84         for (i=1;i<=n;i++)
85           scanf("%d%d",&black[i].x,&black[i].y);
86         for (i=1;i<=n;i++)
87           for (j=1;j<=n;j++) 
88           {
89               w[i][j]=-dis(i,j);
90               if (px[i]<w[i][j])
91                 px[i]=w[i][j];
92           }
93         KM();
94         for (i=1;i<=n;i++)
95           printf("%d\n",fa[i]);
96     }
97 }
bubuko.com,布布扣

poj 3565 uva 1411 Ants KM算法求最小权,布布扣,bubuko.com

poj 3565 uva 1411 Ants KM算法求最小权

原文:http://www.cnblogs.com/handsomeJian/p/3575536.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!