大意:

poj3565Ants【最小权匹配】左图为一个坐标轴上的点  其中黑点代表ants 白点代表apple 问怎样安排ants匹配apple才能使人一两条边不想交

分析:

 

poj3565Ants【最小权匹配】

如左图,我们假设a->d,b->c为一个最佳匹配  交点为e

那么ad+bc = ae+ ed + be + ec = (ae + ec) + (be + ed)  该值大于ac+bd

所以匹配为最佳匹配不成立

因此我们只要求出二分图的最小匹配就是结果了

但是wa了;

wa的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const long long maxn = 105;
 7 const long long INF = 10000000000;
 8 
 9 
10 long long W[maxn][maxn];
11 long long Lx[maxn], Ly[maxn];
12 long long Left[maxn];
13 bool S[maxn], T[maxn];
14 
15 long long n;
16 
17 bool match(long long i) {
18     S[i] = true;
19     for(long long j = 1; j <= n; j++) if (Lx[i]+Ly[j] == W[i][j] && !T[j]){
20         T[j] = true;
21         if (!Left[j] || match(Left[j])){
22             Left[j] = i;
23             return true;
24         }
25     }
26     return false;
27 }
28 
29 void update() {
30     long long a = INF;
31     for(long long i = 1; i <= n; i++) if(S[i])
32         for(long long j = 1; j <= n; j++) if(!T[j])
33             a = min(a, Lx[i]+Ly[j] - W[i][j]);
34     for(long long i = 1; i <= n; i++) {
35         if(S[i]) Lx[i] -= a;
36         if(T[i]) Ly[i] += a;
37     }
38 }
39 
40 void KM() {
41     for(long long i = 1; i <= n; i++) {
42         Left[i] = Lx[i] = Ly[i] = 0;
43         for(long long j = 1; j <= n; j++)
44             Lx[i] = max(Lx[i], W[i][j]);
45     }
46     for(long long i = 1; i <= n; i++) {
47         for(;;) {
48             for(long long j = 1; j <= n; j++) S[j] = T[j] = false;
49             if(match(i)) break; else update();
50         }
51     }
52 }
53 
54 
55 struct Node {
56     long long x, y;
57 }ant[maxn], apple[maxn];
58 
59 
60 long long dist(Node n1, Node n2) {
61     return (n1.x - n2.x) * (n1.x - n2.x) + (n1.y - n2.y) * (n1.y - n2.y);
62 }
63 
64 int main() {
65     while(EOF != scanf("%lld",&n)) {
66         for(long long i = 1; i <= n; i++) scanf("%lld %lld",&ant[i].x, &ant[i].y);
67         for(long long i = 1; i <= n; i++) scanf("%lld %lld",&apple[i].x, &apple[i].y);
68         memset(W, 0, sizeof(W));
69         for(long long i = 1; i <= n; i++) {
70             for(long long j = 1; j <= n; j++) {
71                 W[i][j] = -dist(apple[i], ant[j]);
72             }
73         }
74         KM();
75         for(long long i = 1; i <= n; i++) {
76             printf("%lld\n",Left[i]);
77         }
78     }
79     return 0;
80 }
wa的代码

相关文章:

  • 2021-08-14
  • 2022-12-23
  • 2021-07-19
  • 2022-12-23
  • 2022-12-23
  • 2021-06-10
  • 2022-12-23
  • 2021-11-13
猜你喜欢
  • 2021-07-19
  • 2021-05-17
  • 2022-12-23
  • 2022-02-08
  • 2021-05-31
  • 2022-12-23
  • 2021-08-02
相关资源
相似解决方案