Topic Portal
List
A person to do 12 years north of the problem, oneself or is too weak, the knowledge of graph theory forget light, the smallest generation tree bare inscribed not to come, Dijkstra tle don't know with SPFA.
Simple geometry (Point-to-line distance) + three-part B stealing a Cake
Test instructions: The shortest distance from a point to a circle and then to a rectangle outside the circle.
Analysis: Because the circle in [0, Pi] and [Pi, pi*2] is a single-peak function, with three points to find the extremum, it should be in [0,pi*2] is also a single-peak function bar.
/************************************************* author:running_time* Created TIME:2015/11/7 Saturday 17:24:32* Fil E Name:B_2.cpp ************************************************/#include <cstdio> #include <algorithm># Include <iostream> #include <sstream> #include <cstring> #include <cmath> #include <string > #include <vector> #include <queue> #include <deque> #include <stack> #include <list># Include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime>using namespace std; #define Lson L, Mid, RT << 1#define Rson mid + 1, R, RT << 1 | 1typedef long ll;const int N = 1e5 + 10;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;const Double EPS = 1e-10;c Onst Double PI = ACOs ( -1.0), int dcmp (double x) {//three state function, reduced accuracy problem if (fabs (x) < EPS) return 0; else return x < 0? -1:1;} struct Point {//points defined by double x, y; Point () {} Point (Double x, double y): X (x), Y (y) {}-operator + (const point &r) const {//vector addition retur N Point (x + r.x, y + r.y); } Point operator-(const point &r) const {//Vector subtraction return point (x-r.x, Y-R.Y); } Point operator * (double p) const {//vector multiplied by a scalar return point (x * p, Y * p); } point operator/(double p) const {//vector divided by scalar return point (x/p, y/p); } BOOL operator < (const point &r) const {//DOT coordinate sort return x < R.x | | (x = = r.x && y < r.y); } bool operator = = (Const point &r) const {//judgment same dot return dcmp (x-r.x) = = 0 && dcmp (y-r . y) = = 0; }};typedef Point Vector; Vector definition point read_point (void) {//points read in double x, y; scanf ("%lf%lf", &x, &y); Return point (x, y);} Double dot (vector A, vector B) {//vector dot product return a.x * b.x + a.y * B.Y;} Double Cross (vector A, vector B) {//vectorsCross product return a.x * B.Y-A.Y * b.x;} Vector Rotate (vector A, double rad) {return vector (a.x * cos (RAD)-A.y * sin (rad), a.x * sin (rad) + a.y * cos (RA d));} Double Length (Vector a) {return sqrt (dot (A, a));} Double angle (vector a, vector b) {//Vector corner, counterclockwise, dot product return ACOs (dot (A, b)/Length (a)/length (b));} Double point_to_seg (point P, point A, point B) {if (a = = b) return length (P-A); Vector V1 = b-a, V2 = p-a, V3 = P-b; if (DCMP (dot (V1, V2)) < 0) return length (V2); else if (dcmp (dot (V1, V3)) > 0) return length (V3); else return Fabs (cross (V1, V2))/Length (V1);} struct Circle {point C; Double R; Circle () {} circle (point C, Double R): C (c), R (r) {}-point-point (double a) {return-point (c.x + cos ( A) * R, C.y + sin (a) * R); }}; Point S, a, B, C, D; Circle c;double Cal_dis (double rad) {Point P = c.point (RAD); Double dis1 = Length (s-p); Double dis2 = 1e9; Dis2 = min (dIs2, Point_to_seg (p, a, b)); Dis2 = min (Dis2, point_to_seg (p, B, c)); Dis2 = min (Dis2, point_to_seg (p, C, D)); Dis2 = min (Dis2, point_to_seg (P, D, a)); return dis1 + Dis2;} int main (void) {Double x, y, R, x2, y2; while (scanf ("%lf%lf", &x, &y) = = 2) {if (dcmp (x) = = 0 && dcmp (y) = = 0) Break;s = point (x, y); scanf ("%l F%lf%lf ", &x, &y, &r); C = Circle (Circle (Point (x, y), R)); scanf ("%lf%lf%lf%lf", &x, &y, &x2, &y2); A = Point (min (x, x2), Max (Y, y2)); b = Point (min (x, x2), min (y, y2)); c = Point (max (x, x2), min (y, y2)); D = Point (max (x, x2), Max (Y, y2)); Vector v[2]; int cnt = Point_cir_tan (S, C, V); Double L = angle (vector (1, 0), v[0]), r = Angle (vector (1, 0), v[1]); if (L > R) Swap (L, R); while (R-l > EPS) {Double mid = (L + r)/2; Double Lmid = (L + mid)/2; Double Rmid = (R + mid)/2; Double res1 = Cal_dis (lmid), Res2 = Cal_dis (Rmid); if (Res1 < res2) {r = Rmid; } else L = lmid; } printf ("%.2f\n", Cal_dis (l)); } return 0;}
Spfa/bfs H Friend Chains
Test instructions: The shortest possible maximum for any two point
Analysis: Floyd O (n^3) Absolute Timeout, I think Dijkstra,o (v * (Vloge + V), later with SPFA is barely over, no love for Dijkstra. Hangzhou Electric Discuss someone wrote the fastest solution, similar to the diameter of the tree, both sides of the BFS. The problem is that the first to find the furthest point may have multiple, to choose the smallest degree, or more degrees, from the point of departure to some points is not the farthest, is not the diameter.
Spfa
#include <bits/stdc++.h>using namespace Std;const int N = 1e3 + 10;const int E = 2e4 + 10;const int INF = 0x3f3f3f3f ; struct Edge{int V, W, NEX; Edge () {} edge (int V, double w, int nex): V (v), W (W), NEX (NEX) {}}edge[e];int head[n];bool vis[n];int d[n];int N, M, e;void init (void) {memset (head,-1, sizeof (head)); e = 0;} void Add_edge (int u, int v, int w) {Edge[e] = Edge (V, W, Head[u]); Head[u] = e++;} void SPFA (int s) {for (int i=1; i<=n; ++i) {Vis[i] = false; D[i] = INF; } Vis[s] = true; D[s] = 0; Queue<int> Q; Q.push (s); while (! Q.empty ()) {int u = q.front (); Q.pop (); Vis[u] = false; for (int i=head[u]; ~i; i=edge[i].nex) {int v = edge[i].v, w = EDGE[I].W; if (D[v] > D[u] + W) {D[v] = D[u] + W; if (!vis[v]) {Vis[v] = true; Q.push (v); }}}}}map<string, int> Id;char str1[11], Str2[11];int main (void) {while (scanf ("%d", &n) = = 1) {if (!n) break;id.clear (); for (int i=1; i<=n; ++i) { scanf ("%s", &STR1); ID[STR1] = i;} Init (); scanf ("%d", &m), for (int i=1; i<=m; ++i) {scanf ("%s%s", &str1, &STR2); if (id[str1] = = Id[str2]) Continue;add_edge (ID[STR1], id[str2], 1); Add_edge (ID[STR2], id[str1], 1);} int ans = 0;for (int i=1; i<=n; ++i) {SPFA (i); for (int j=1; j<=n; ++j) {if (d[j] = = INF) {ans =-1; Break } if (ans < d[j]) ans = d[j]; } if (ans = =-1) break; }printf ("%d\n", ans); return 0;}
BFS
/************************************************* author:running_time* Created TIME:2015/11/7 Saturday 16:16:25* Fil E Name:H_2.cpp ************************************************/#include <bits/stdc++.h>using namespace std;# Define Lson L, Mid, RT << 1#define Rson mid + 1, R, RT << 1 | 1typedef long ll;const int N = 1e3 + 10;const int E = 2e4 + 10;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;con St Double EPS = 1e-10;const Double PI = ACOs ( -1.0); struct Edge{int V, W, NEX; Edge () {} edge (int v, int w, int nex): V (v), W (W), NEX (NEX) {}}edge[e];int head[n], d[n], Deg[n];bool vis[n];int N, M, e;void init (void) {memset (head,-1, sizeof (head)); memset (deg, 0, sizeof (deg)); e = 0;} void Add_edge (int u, int v, int w) {Edge[e] = Edge (V, W, Head[u]); Head[u] = e++;} int BFS (int s) {for (int i=1; i<=n; ++i) {D[i] = (i = = s)? 0:inf; Vis[i] = (i = = s)? True:false; } queue<int> Q; Q.push (s); InchT idx = 0, mx = 0; while (! Q.empty ()) {int u = q.front (); Q.pop (); for (int i=head[u]; ~i; i=edge[i].nex) {int v = edge[i].v, w = EDGE[I].W; if (Vis[v]) continue; if (D[v] > D[u] + W) {D[v] = D[u] + W; VIS[V] = true; Q.push (v); } if (D[v] > mx | | (D[v] = = mx && deg[v] < DEG[IDX])) {mx = d[v]; idx = v; }}} return idx;} Map<string, int> Id;char str1[11], str2[11];int main (void) {while (scanf ("%d", &n) = = 1) {if (!n) break;id.clear ( ); for (int i=1; i<=n; ++i) {scanf ("%s", &STR1); ID[STR1] = i;} Init (); scanf ("%d", &m), for (int i=1; i<=m; ++i) {scanf ("%s%s", &str1, &STR2); if (id[str1] = = Id[str2]) Continue;add_edge (ID[STR1], id[str2], 1); Add_edge (ID[STR2], id[str1], 1); deg[id[str1]]++; deg[id[str2]]++; }int ans = 0; int idx = BFS (1); Ans = D[BFS (idx)]; for (int i=1; i<=n; ++i) {if (d[i] = = INF) {ans =-1; Break }} printf ("%d\n", ans);} return 0;}
Water I The Power of Xiangqi
A game of chess before the race, unexpectedly ran into the topic of chess.
State Compression + enumeration J scaring the Birds
Test instructions: There are a few points can put the Scarecrow, ask at least put a few scarecrow to protect so straw
Analysis: There is no trap, mainly look at the example of the R range of some tangled, put the scarecrow point of No straw. As long as the pressure enumeration to put the number and position on it.
#include <bits/stdc++.h>using namespace Std;const int N = 55;const int INF = 0x3f3f3f3f;struct point{int x, Y, R , step; Point () {} point (int x, int y, int step): X (x), Y (y), step (step) {}}p[11];int n, m;int a[n][n];bool vis[n][n];int Dx[] = {-1, 1, 0, 0};int dy[] = {0, 0,-1, 1};void map_init (void) {for (Int. I=1; i<=n; ++i) {for (int j=1; j <=n; ++J) A[i][j] = 0; } for (int i=0; i<m; ++i) {a[p[i].x][p[i].y] = 1; }}bool judge (void) {for (int i=1, i<=n; ++i) {for (int j=1; j<=n; ++j) {if (!a[i][j]) return FAL Se }} return true; BOOL Check (int x, int y) {if (x < 1 | | x > N | | y < 1 | | y > N | | vis[x][y]) return false; Elsereturn true;} void BFS (int u) {int R = p[u].r;vis[p[u].x][p[u].y] = true; Queue<point> Q; Q.push (Point (p[u].x, P[U].Y, 0)); while (! Q.empty ()) {Point r = Q.front (); Q.pop (); if (R.step > R) continue; A[R.X][R.Y] = 1; for (int i=0; i<4; ++i) {int tx = r.x + Dx[i], Ty = R.y + dy[i]; if (!check (TX, Ty)) continue; Vis[tx][ty] = true; Q.push (Point (TX, Ty, R.step + 1)); }}}int Main (void) {while (scanf ("%d", &n) = = 1) {if (!n) break; scanf ("%d", &m); for (int i=0; i<m; ++i) {scanf ("%d%d", &p[i].x, &P[I].Y); } for (int i=0; i<m; ++i) {scanf ("%d", &P[I].R); } int S = 1 << m; int ans = INF; for (int i=0; i<s; ++i) {int num = __builtin_popcount (i); Map_init (); for (int j=0; j<m; ++j) {if (I & (1 << j)) {memset (Vis, false, sizeof (vis )); BFS (j); }} if (!judge ()) continue; ans = min (ans, num); } if (ans = = INF) puts ("-1"); elseprintf ("%d\n", ans); } return 0;}
Minimum spanning tree K Outlets
Test instructions: Minimum spanning tree, limit is p and Q must have edge connection
Analysis: As the second water topic I could not write, Kruskal method before the P and Q connect the top on the line, or prim in p to Q distance to 0 (priority out of the queue), and then add back.
Kruskal
#include <bits/stdc++.h>using namespace Std;const int N = 55;const int E = n * n;const double INF = 1e9;struct edge{ int u, v;double w; Edge () {} edge (int u, int v, double w): U (U), V (v), W (w) {} BOOL operator < (const Edge &r) Const {Retu RN W < R.W; }}edge[e];struct UF {int rt[n], rk[n]; void init (void) {memset (RT,-1, sizeof (RT)); memset (RK, 0, sizeof (RK)); } int Find (int x) {return rt[x] = =-1? x:rt[x] = Find (rt[x]); } void Union (int x, int y) {x = Find (x); y = Find (y); if (x = = y) return; if (Rk[x] > Rk[y]) {rt[y] = x; RK[X] + = Rk[y]; } else {rt[x] = y; Rk[y] + = rk[x]; }}}uf;int X[n], y[n];int tot;double sqr (int x, int y) {return (double) (x * x + y * y);} Double Cal_dis (int i, int j) {return sqrt (SQR (X[i]-x[j], Y[i]-y[j]));} void Add_edge (int u, int v, double w) {edge[tot++] = Edge (U, V, W);} int p, Q;int main(void) {int N;while (scanf ("%d", &n) = = 1) {if (!n) break;scanf ("%d%d", &p, &q), if (p > Q) Swap (p, q); for (int i=1; i<=n; ++i) {scanf ("%d%d", &x[i], &y[i]);} Uf.init (); Tot = 0;double ans = Cal_dis (p, q); UF.RT[P] = q; for (int i=1; i<=n; ++i) {for (int j=i+1; j<=n; ++j) {Add_edge (I, J, Cal_dis (I, j)); }} sort (Edge, edge+tot); for (int i=0; i<tot; ++i) {int u = edge[i].u, v = edge[i].v; Double w = EDGE[I].W; U = uf. Find (U); v = uf. Find (v); if (U = = v) continue; Ans + = w; uf. Union (U, v); }printf ("%.2f\n", ans); return 0;}
Prim
#include <bits/stdc++.h>using namespace Std;const int N = 55;const int E = n * n;const double INF = 1e9;struct edge{ int V, nex;double W; Edge () {} edge (int V, double w, int nex): V (v), W (W), NEX (NEX) {} BOOL operator < (const Edge &R) const {return w > R.W; }}edge[e];int Head[n];bool Vis[n];d ouble d[n];int x[n], Y[n];int p, Q, e;void init (void) {memset (head,-1, sizeof (head)); e = 0;} void Add_edge (int u, int v, double w) {Edge[e] = Edge (V, W, Head[u]); Head[u] = e++;} Double Sqr (int x, int y) {return (double) (x * x + y * y);} Double Cal_dis (int i, int j) {return sqrt (SQR (X[i]-x[j], Y[i]-y[j]));} Double Prim (int s) {memset (Vis, false, sizeof (VIS)); for (int i=0; i<55; ++i) d[i] = inf;priority_queue<edge> Q;do uble ret = 0; for (int i=head[s]; ~i; i=edge[i].nex) {int v = edge[i].v;double W = edge[i].w;if (D[v] > W) {d[v] = W; if (v = = q) {ret + = D[v]; D[V] = 0; } Q.push (Edge (V, D[v], 0));}} Vis[s] = true; D[s] = 0;while (! Q.empty ()) {int u = q.top (). V; Q.pop (), if (Vis[u]) continue;vis[u] = True;ret + = d[u];for (int i=head[u]; ~i; i=edge[i].nex) {int v = edge[i].v;double W = Edge[i].w;if (v = = q) continue;if (!vis[v] && D[v] > W) {d[v] = W; Q.push (Edge (V, D[v], 0));}}} return ret;} int main (void) {int n;while (scanf ("%d", &n) = = 1) {if (!n) break;scanf ("%d%d", &p, &q), if (p > Q) swap (p, Q); for (int i=1; i<=n; ++i) {scanf ("%d%d", &x[i], &y[i]);} Init (); for (int. i=1; i<=n; ++i) {for (int j=i+1; j<=n; ++j) {Add_edge (I, J, Cal_dis (I, J)); Add_edge (J, I, Cal_dis (i, J));}} printf ("%.2f\n", Prim (P));} return 0;}
Regionals:: Hangzhou