-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path10080-GopherII.cpp
executable file
·141 lines (130 loc) · 2.94 KB
/
10080-GopherII.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//
// 10080 - Gopher II.cpp
// Uva
//
// Created by Alexander Faxå on 2012-02-19.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#define MAX_SOURCES 100
#define MAX_DESTS 100
using namespace std;
struct vsrc;
struct vdest
{
vsrc* conn; // Set to 0 or suggest connections, counted iff 0
vsrc* sugg; // Suggestion to new connection
};
struct vsrc
{
vector<vdest*> d;
vdest* conn; // Set to 0 or suggest connections, counted iff 0
vsrc* aug; // Sources: Augmenting path start (= 0 iff not queued)
};
struct point
{
double x, y;
};
vsrc vs[MAX_SOURCES];
int nums;
vdest vd[MAX_DESTS];
int numd;
int s, v;
void FixAugPath(vdest* dest)
{
for(;;)
{
vsrc* src = dest->sugg;
// Add src->dest
dest->conn = src;
if(!src->conn)
{
src->conn = dest;
break;
}
// src already used, fix the src's connection too
vdest* other = src->conn;
src->conn = dest;
dest = other;
}
}
int BipartiteMatching() {
int flow = 0;
bool foundPath;
do
{
vsrc* q[MAX_SOURCES];
int qs = 0, qe = 0;
foundPath = false;
// Find all potential beginnings of shortest augmenting paths
for(int i = 0; i < nums; ++i)
{
if((vs[i].aug = (vs[i].conn ? 0 : &vs[i])))
q[qe++] = &vs[i]; // Push to queue if no connection
}
for(int j = 0; j < numd; ++j)
vd[j].sugg = 0;
// Find all endings of shortest (all same lengths) aug-paths
while(!foundPath && qs < qe)
{
// Let the BFS go through the next layer
for(int qecl = qe;qs < qecl; ++qs) // End of current layer
{
vsrc* src = q[qs];
if(src->aug->conn) // My augmenting path start is
continue; // already used
// Check edges
for(int i = 0; i < src->d.size(); ++i)
{
vdest* dest = src->d[i];
if(dest == src->conn) // Find a better one than
continue; // the current connection
if(dest->sugg) // Already in some other
continue; // augmenting path
dest->sugg = src;
if(!dest->conn)
{
foundPath = true;
FixAugPath(dest);
++flow;
break; // Found a path
}
vsrc* o = dest->conn;
if(!o->aug)
{ // Push to queue, next layer due to qe >= qecl
q[qe++] = o;
o->aug = src->aug;
}
}
}
}
} while(foundPath);
return flow;
}
int main()
{
while(cin >> nums >> numd >> s >> v)
{
point coords[nums];
for (int i = 0; i < nums; i++) {
cin >> coords[i].x >> coords[i].y;
vs[i].d.clear();
vs[i].conn = 0;
}
for (int i = 0; i < numd; i++) {
vd[i].conn = 0;
double dx, dy;
cin >> dx >> dy;
for (int j = 0; j < nums; j++) {
if(sqrt(pow(dx-coords[j].x,2) + pow(dy-coords[j].y,2)) / (double)v <= s + 1e-10){
vs[j].d.push_back(&vd[i]);
}
}
}
cout << nums - BipartiteMatching() << endl;
}
return 0;
}