Submission #00153


ソースコード

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
#include <bits/stdc++.h>
using namespace std;
#define EPS (1e-6)
#define equals(a, b) (fabs((a) - (b)))
struct Edge
{
int a, b;
double cost;
Edge () {}
Edge (int a, int b, double cost) : a(a), b(b), cost(cost) {}
bool operator < (const Edge d) const { return (cost < d.cost); }
};
struct Point
{
double x, y;
int num;
Point () {}
Point (double x, double y, int num) : x(x), y(y), num(num) {}
void input(int n) { scanf("%lf %lf", &x, &y); num = n; }
double norm() { return (x * x + y * y); }
double abs() { return (sqrt(norm())); }
Point operator + (Point d) { return ( Point(x + d.x, y + d.y, 0) ); }
Point operator - () { return ( Point(-x, -y, 0) ); }
Point operator - (Point d) { return (*this + -d); }
Point operator * (double d) { return ( Point(x * d, y * d, 0) ); }
Point operator / (double d) { return ( Point(x / d, y / d, 0) ); }
bool operator < (const Point d) const { return (x < d.x || x == d.x && y < d.y); }
};
struct UF
{
int parent[105];
UF() { for(int i = 0; i < 105; i++) parent[i] = i; }
int root(int n) { return parent[n] = ( parent[n] == n ? n : root(parent[n]) ); }
bool unite(int a, int b)
{
a = root(a), b = root(b);
if(a == b) return (false);
parent[a] = b;
return (true);
}
};
typedef Point Vector;
typedef vector < Point > Polygon;
double cross(Vector a, Vector b) { return (a.x * b.y - a.y * b.x); }
int ccw(Point p0, Point p1, Point p2)
{
Vector a = p1 - p0, b = p2 - p0;
double val = cross(a, b);
if(val < -EPS) return (-1); // tokei
else if(val > EPS) return (1);
return (0);
}
Polygon Andrew(Polygon pl)
{
Polygon u, l;
if(pl.size() < 3) return (pl);
sort(pl.begin(), pl.end());
u.push_back(pl[0]); u.push_back(pl[1]);
l.push_back(pl[pl.size() - 1]); l.push_back(pl[pl.size() - 2]);
for(int i = 2; i < pl.size(); i++) {
while(u.size() >= 2 && ccw(u[u.size() - 2], u[u.size() - 1], pl[i]) >= 0) u.pop_back();
u.push_back(pl[i]);
}
for(int i = pl.size() - 3; i >= 0; i--) {
while(l.size() >= 2 && ccw(l[l.size() - 2], l[l.size() - 1], pl[i]) >= 0) l.pop_back();
l.push_back(pl[i]);
}
for(int i = 1; i < l.size() - 1; i++) u.push_back(l[i]);
return (u);
}
int main()
{
int V, R;
Polygon P, T;
vector < Edge > ed;
double ans = 0.0;
UF tree;
cin >> V >> R;
for(int i = 0; i < V; i++) {
Point p;
p.input(i);
P.push_back(p);
}
for(int i = 0; i < R; i++) {
int a, b;
cin >> a >> b; --a, --b;
ed.push_back(Edge(a, b, (P[a] - P[b]).abs()));
}
T = Andrew(P);
for(int i = 0; i < T.size(); i++) {
ans += (T[i] - T[(i + 1) % T.size()]).abs();
tree.unite(T[i].num, T[(i + 1) % T.size()].num);
}
sort(ed.begin(), ed.end());
for(int i = 0; i < ed.size(); i++) {
if(tree.unite(ed[i].a, ed[i].b)) ans += ed[i].cost;
}
printf("%.10f\n", ans);
return (0);
}

ステータス

項目 データ
問題 0008 - 村の道路計画
ユーザー名 Eraim Unit
投稿日時 2017-09-06 17:22:53
言語 C++
状態 Accepted
得点 14
ソースコード長 3152 Byte
最大実行時間 59 ms
最大メモリ使用量 760 KB

セット

セット 得点 Cases
1 ALL 14 / 14 *

テストケース

ファイル名 状態 実行時間 メモリ使用量 #
in01.txt AC 41 ms 608 KB
1
in02.txt AC 28 ms 448 KB
1
in03.txt AC 23 ms 420 KB
1
in04.txt AC 19 ms 524 KB
1
in05.txt AC 17 ms 500 KB
1
in06.txt AC 17 ms 600 KB
1
in07.txt AC 59 ms 576 KB
1
in08.txt AC 15 ms 556 KB
1
in09.txt AC 23 ms 644 KB
1
in10.txt AC 18 ms 604 KB
1
in11.txt AC 24 ms 684 KB
1
in12.txt AC 18 ms 640 KB
1
in13.txt AC 22 ms 720 KB
1
in14.txt AC 18 ms 672 KB
1
in15.txt AC 24 ms 636 KB
1
in16.txt AC 23 ms 724 KB
1
in17.txt AC 29 ms 676 KB
1
in18.txt AC 24 ms 760 KB
1