3565

1 /*
2 配对问题,蚂蚁和苹果树之间的距离和最小的时候,肯定是不相交的时候
3
4 利用的是三角不等式原理
5
6 可用KM算法解决
7 */
8
9 // include file
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 #include <cmath>
14 #include <cctype>
15 #include <ctime>
16
17 #include <iostream>
18 #include <sstream>
19 #include <fstream>
20 #include <iomanip>
21 #include <bitset>
22 #include <strstream>
23
24 #include <algorithm>
25 #include <string>
26 #include <vector>
27 #include <queue>
28 #include <set>
29 #include <list>
30 #include <functional>
31
32 using namespace std;
33
34 // typedef
35 typedef long long LL;
36 typedef unsigned long long ULL;
37
38 //
39 #define read freopen("in.txt","r",stdin)
40 #define write freopen("out.txt","w",stdout)
41 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
42 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
43 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
44 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
45 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
46 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
47 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
48
49 #define FF(i,a) for(int i=0;i<(a);i+++)
50 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
51 #define Z(a) (a<<1)
52 #define Y(a) (a>>1)
53
54 const double eps = 1e-6;
55 const double INFf = 1e10;
56 const int INFi = 1000000000;
57 const double Pi = acos(-1.0);
58
59 template<class T> inline T sqr(T a){return a*a;}
60 template<class T> inline T TMAX(T x,T y)
61 {
62 if(x>y) return x;
63 return y;
64 }
65 template<class T> inline T TMIN(T x,T y)
66 {
67 if(x<y) return x;
68 return y;
69 }
70 template<class T> inline void SWAP(T &x,T &y)
71 {
72 T t = x;
73 x = y;
74 y = t;
75 }
76 template<class T> inline T MMAX(T x,T y,T z)
77 {
78 return TMAX(TMAX(x,y),z);
79 }
80
81
82 // code begin
83 #define MAXN 110
84 double cost[MAXN][MAXN];
85 int mt[MAXN];
86 double lx[MAXN];
87 double ly[MAXN];
88 bool S[MAXN];
89 bool T[MAXN];
90 bool used[MAXN];
91 struct node
92 {
93 double x;
94 double y;
95 };
96 node ant[MAXN];
97 node app[MAXN];
98 int N;
99
100 bool hungarian_MM(int i)
101 {
102 S[i] = true;
103 FORj(0,N,1)
104 {
105 if(!T[j] && fabs(lx[i]+ly[j]-cost[i][j])<1e-6 )
106 {
107 T[j]=true;
108 if( mt[j]==-1 || hungarian_MM(mt[j]))
109 {
110 mt[j] = i;
111 return true;
112 }
113 }
114 }
115 return false;
116 }
117
118 void KM_PM(bool flag=true) //true时最大,否则最小
119 {
120 if(!flag)
121 {
122 FORi(0,N,1)
123 {
124 FORj(0,N,1)
125 {
126 cost[i][j] = -cost[i][j];
127 }
128 }
129 }
130
131 // 初试化顶标
132 FORi(0,N,1)
133 {
134 lx[i] = -INFf;
135 ly[i] = 0;
136 FORj(0,N,1)
137 {
138 lx[i] = TMAX(lx[i],cost[i][j]);
139 }
140 }
141
142 memset(mt,-1,sizeof(int)*MAXN);
143 FORi(0,N,1)
144 {
145 while(true)
146 {
147 memset(S,0,sizeof(bool)*MAXN);
148 memset(T,0,sizeof(bool)*MAXN);
149 if( hungarian_MM(i))
150 break;
151
152 // 找d
153 double d = INFf;
154
155 FORj(0,N,1)
156 {
157 if(S[j])
158 {
159 FORk(0,N,1)
160 {
161 if(!T[k])
162 {
163 d = TMIN(d,lx[j]+ly[k]-cost[j][k]);
164 }
165 }
166 }
167 }
168
169 // gengxin
170 FORj(0,N,1)
171 {
172 if(S[j])
173 lx[j] -=d;
174 if(T[j])
175 ly[j] +=d;
176 }
177 }
178 }
179
180 // 找打匹配了
181 FORi(0,N,1)
182 {
183 FORj(0,N,1)
184 {
185 if(mt[j]==i)
186 {
187 printf("%d\n",j+1);
188 break;
189 }
190 }
191 }
192 }
193
194 double getDis(int i,int j)
195 {
196 return sqrt( (ant[i].x-app[j].x)*(ant[i].x-app[j].x)+(ant[i].y-app[j].y)*(ant[i].y-app[j].y) );
197 }
198
199 int main()
200 {
201 read;
202 write;
203 double x,y;
204 while(scanf("%d",&N)!=-1)
205 {
206 FORi(0,N,1)
207 {
208 scanf("%lf %lf",&ant[i].x,&ant[i].y);
209 }
210 FORi(0,N,1)
211 {
212 scanf("%lf %lf",&app[i].x,&app[i].y);
213 }
214 FORi(0,N,1)
215 {
216 FORj(0,N,1)
217 {
218 cost[i][j] = getDis(i,j);
219 }
220 }
221 KM_PM(false);
222 }
223 return 0;
224 }
posted @ 2011-03-07 18:20  AC2012  阅读(729)  评论(0编辑  收藏  举报