[XSY 1145] 网络战争 平面最近点对 最小割树
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[XSY 1145] 网络战争 平面最近点对 最小割树相关的知识,希望对你有一定的参考价值。
码农题.
LEN 开到 1000 比较稳.
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <algorithm> 6 #include <vector> 7 using namespace std; 8 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 9 #define LL long long 10 inline int rd(void) { 11 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 12 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 13 } 14 15 const int N = 50005; 16 const int Ni = 2005; 17 const int Mi = 4005; 18 const int S = 100005; 19 const int INF = ~0u>>2; 20 const int LEN = 1000; 21 22 int n, Start[N]; 23 24 int List[Ni], tmp[Ni]; bool Vis[Ni]; 25 26 struct Edge { int v, f, nx; }mp[Mi]; int tot, hd[Ni]; 27 int q[Ni], qh, qt, Lev[Ni]; 28 inline void Init(int x, int y, int w) { 29 mp[++tot] = (Edge){y, w, hd[x]}, hd[x] = tot; 30 mp[++tot] = (Edge){x, w, hd[y]}, hd[y] = tot; 31 } 32 33 struct E { int v, d; }; vector<E> g[S]; 34 inline void Add(int x, int y, int w) { g[x].push_back((E){y, w}), g[y].push_back((E){x, w}); } 35 36 bool BFS(int s, int t) { 37 memset(q, 0, sizeof q), qh = qt = 0, memset(Lev, -1, sizeof Lev); 38 q[++qt] = s, Lev[s] = 0; 39 while (qh != qt) { 40 int x = q[++qh]; 41 for (int k = hd[x]; k > 0; k = mp[k].nx) 42 if (mp[k].f > 0 && Lev[mp[k].v] == -1) { 43 Lev[mp[k].v] = Lev[x]+1; 44 if (mp[k].v == t) return true; 45 q[++qt] = mp[k].v; 46 } 47 } 48 return false; 49 } 50 int DFS(int x, int t, int flow) { 51 if (x == t) return flow; 52 int sum = 0; 53 for (int k = hd[x]; k > 0; k = mp[k].nx) 54 if (mp[k].f > 0 && Lev[mp[k].v] == Lev[x]+1) { 55 int tmp = DFS(mp[k].v, t, min(flow, mp[k].f)); 56 if (tmp > 0) { 57 mp[k].f -= tmp, mp[k^1].f += tmp; 58 sum += tmp, flow -= tmp; 59 if (!flow) break; 60 } 61 else Lev[mp[k].v] = INF; 62 } 63 return sum; 64 } 65 void Paint(int x) { 66 Vis[x] = true; 67 for (int k = hd[x]; k > 0; k = mp[k].nx) 68 if (mp[k].f > 0 && !Vis[mp[k].v]) 69 Paint(mp[k].v); 70 } 71 void Solve(int Bg, int L, int R) { 72 if (L == R) return; 73 74 int s = List[L], t = List[R]; 75 for (int i = 2; i <= tot; i += 2) 76 mp[i].f = mp[i^1].f = (mp[i].f + mp[i^1].f) >> 1; 77 78 int sum = 0; 79 while (BFS(s, t)) 80 sum += DFS(s, t, INF); 81 memset(Vis, false, sizeof Vis); 82 Paint(s); 83 84 Add(Bg + s, Bg + t, sum); 85 F(i, L, R) tmp[i] = List[i]; 86 int curL = L, curR = R; 87 F(i, L, R) 88 Vis[tmp[i]] ? List[curL++] = tmp[i] : List[curR--] = tmp[i]; 89 Solve(Bg, L, curL-1); 90 Solve(Bg, curR+1, R); 91 } 92 93 void Build(int Bg, int n, int m) { 94 tot = 1, memset(hd, 0, sizeof hd); 95 F(i, 1, m) { 96 int x = rd(), y = rd(), w = rd(); 97 Init(x, y, w); 98 } 99 100 F(i, 1, n) List[i] = i; 101 random_shuffle(List+1, List+n+1); 102 Solve(Bg, 1, n); 103 } 104 105 int val[N], id[N], ord[N]; 106 struct point { int x, y; }p[N]; 107 108 inline bool cmpx(int i, int j) { return p[i].x < p[j].x; } 109 inline bool cmpy(int i, int j) { return p[i].y < p[j].y; } 110 inline LL Dist(point A, point B) { return 1LL * (A.x - B.x) * (A.x - B.x) + 1LL * (A.y - B.y) * (A.y - B.y); } 111 void Up(void) { 112 F(i, 1, n) { 113 int L = max(1, i-LEN), R = min(n, i+LEN), cur = ord[i]; 114 F(j, L, R) if (i != j) { 115 int Dx = Dist(p[cur], p[id[cur]]), Dy = Dist(p[cur], p[ord[j]]); 116 if (Dx > Dy || (Dx == Dy && id[cur] > ord[j])) 117 id[cur] = ord[j]; 118 } 119 } 120 } 121 122 int par[S], key[S], dep[S]; 123 void Prework(int x) { 124 for (vector<E>::iterator it = g[x].begin(); it != g[x].end(); it++) 125 if (par[x] != it->v) { 126 if (par[it->v] > 0) { key[it->v] += it->d; continue; } 127 par[it->v] = x, key[it->v] = it->d, dep[it->v] = dep[x]+1; 128 Prework(it->v); 129 } 130 } 131 inline int Query(int x, int y) { 132 int res = INF; 133 if (dep[x] < dep[y]) swap(x, y); 134 for (; dep[x] != dep[y]; x = par[x]) 135 res = min(res, key[x]); 136 for (; x != y; x = par[x], y = par[y]) 137 res = min(res, key[x]), res = min(res, key[y]); 138 // If x and y is not connected, the answer should be zero 139 // and I can get zero through ( par[root] = 0, key[root] = 0 ) 140 return res; 141 } 142 143 int main(void) { 144 #ifndef ONLINE_JUDGE 145 freopen("network.in", "r", stdin); 146 #endif 147 148 n = rd(); 149 F(j, 1, n) { 150 int x = rd(); p[j] = (point){x, rd()}; 151 val[j] = rd(); 152 153 int ni = rd(), mi = rd(); 154 Start[j+1] = Start[j] + ni; 155 156 Build(Start[j], ni, mi); 157 } 158 159 if (n != 1) { 160 F(i, 1, n) id[i] = 1 + (i == 1); 161 F(i, 1, n) ord[i] = i; 162 sort(ord+1, ord+n+1, cmpx); 163 Up(); 164 sort(ord+1, ord+n+1, cmpy); 165 Up(); 166 F(i, 1, n) 167 Add(Start[i]+1, Start[id[i]]+1, val[i]); 168 } 169 170 F(i, 1, Start[n+1]) 171 if (!key[i]) dep[i] = 1, Prework(i); 172 173 int q = rd(); 174 F(t, 1, q) { 175 int ta = rd(), tb = rd(), qa = rd(), qb = rd(); 176 printf("%d\n", Query(Start[ta] + qa, Start[tb] + qb)); 177 } 178 179 return 0; 180 }
以上是关于[XSY 1145] 网络战争 平面最近点对 最小割树的主要内容,如果未能解决你的问题,请参考以下文章