Dynamic network flow, SGU 438

Source: Internet
Author: User

There is a East-West River with W in width. There are N stones in the river. The coordinates of each rock (Xi, Yi) and the maximum number of people bearing Ci are known. Now there are M tourists on the south bank of the river. They want to cross the river, but each person can only jump D meters at a time, each jump takes 1 second. They asked if they could all cross the river. If they could, it would take at least a long time. <= N <= 50, 0 <M <= 50, 0 <= D <= 1000, 0 <W (0 <= 1000, 0 <Xi <1000, 0 <Yi <W, 0 <= Ci <= 1000 ). After reading this question, I think it is a minimum cost flow problem. However, after WA, I realized that this question is not to find the maximum stream of a given network, but to calculate how much traffic can be set aside for this network over time. By enumerating the time, we can determine when all the people can be sent to the other side. Note that people can start from any x coordinate on the river. (The start person is on the X axis. the other side can be seen as a straight line of Y = W; because people in this question can stand on the stone, they cannot use the minimum cost stream. we construct a layer of graph for each time point. The first and last layers of the same point are connected to the same point. from t second to t + 1 second without movement if I can reach j after 1 second, then I in the k layer and j edge k + in the k + 1 Layer 1. The time we determine is the maximum time we assume. We can use the binary method to allocate time to it, or we can use brute force to add time. If there are a lot of points, we can use brute force to add edge to the time source points. you don't have to say much about the code comment.

# Include <cstdio> # include <cstring> # include <iostream> # include <cmath> using namespace std; const int maxn = 200*55; const int inf = 0x7fffffff; struct node {int v, next; int val;} s [maxn * 200]; int level [maxn], p [maxn], que [maxn * 200], out [maxn], ind; inline void insert (int x, int y, int z) {s [ind]. v = y; s [ind]. val = z; s [ind]. next = p [x]; p [x] = ind ++; s [ind]. v = x; s [ind]. val = 0; s [ind]. next = p [y]; p [y] = ind ++;} vo Id build_level (int n, int source) {int h = 0, r = 0, I, u; for (I = 0; I <= n; I ++) level [I] = 0; level [source] = 1; que [0] = source; while (h <= r) {u = que [h ++]; for (I = p [u]; I! =-1; I = s [I]. next) {if (s [I]. val & level [s [I]. v] = 0) {que [++ r] = s [I]. v; level [s [I]. v] = level [u] + 1 ;}}} long dinic (long n, long source, long sink) {long ret = 0, I; while (1) {build_level (n, source); if (level [sink] = 0) break; for (I = 0; I <= n; ++ I) out [I] = p [I]; // I wrote an error '='. The result is tle. After debugging for a long time, long q =-1; while (1) {if (q <0) {// empty stack, press the source (if the source edge is not full) for (I = out [source]; I! =-1; I = s [I]. next) {if (s [I]. val & out [s [I]. v]! =-1 & level [s [I]. v] = 2) break;} if (I! =-1) {que [++ q] = I; out [source] = s [I]. next;} else break;} long u = s [que [q]. v; if (u = sink) {long dd = inf; for (I = 0; I <= q; I ++) {if (dd> s [que [I]. val) dd = s [que [I]. val;} ret + = dd; for (I = 0; I <= q; I ++) {s [que [I]. val-= dd; s [que [I] ^ 1]. val + = dd ;}for (I = 0; I <= q; I ++) {// congestion point if (s [que [I]. val = 0) {q = I-1; break ;}} else {for (I = out [u]; I! =-1; I = s [I]. next) {if (s [I]. val & out [s [I]. v]! =-1 & level [u] + 1 = level [s [I]. v]) break;} if (I! =-1) {que [++ q] = I; out [u] = s [I]. next;} else {// The current vertex does not have a feasible stream connecting out [u] =-1; q -- ;}}} return ret;} void ini () {ind = 0; memset (p,-1, sizeof (p);} int dis [55] [55]; int pile [55] [3]; int GetDis (int x1, int y1, int x2, int y2) {int t1 = x1-x2; int t2 = y1-y2; return t1 * t1 + t2 * t2 ;} void Build (int n, int m, int mid, int D, int W) {ini (); // 0 --> super source point; // 2 * n * mid + 1 ---> source point; // 2 * n * mid + 2 --> sink point; // The maximum capacity from a super source to a sink is m insert (* n * mid. + 1, m); for (int k = 0; k <mid; k ++) {for (int I = 1; I <= n; I ++) {insert (2 * k * n + I, 2 * k * n + I, pile [I] [2]); // The first and last layers of the same point are connected // if (pile [I] [1] <= D) of the Source Vertex and the part of the Bipartite Graph) insert (2 * n * mid + 1, 2 * k * n + I, inf ); // connect the Source Vertex to the I-th vertex of each layer // The B-th vertex of the Bipartite Graph if (pile [I] [1] + D> = W) insert (2 * k * n + I, 2 * n * mid + 2, inf ); // the I-th point of each layer is connected to the sink point} // The point I of Part A in the bipartite graph can be directed to Point j for (int I = 1; I <= n; I ++) {for (int j = 1; j <= n; j ++) {if (dis [I] [j] <= D * D) {for (int k = 0; k <mid-1; k ++) {insert (2 * k * n + I, 2 * (k + 1 )* N + j, inf ); // if I can reach j after 1 second, then I in the k layer and j edge in the k + 1 layer }}} int main () {int m, n, D, W; while (scanf ("% d", & n, & m, & D, & W )! = EOF) {ini (); for (int I = 1; I <= n; I ++) scanf ("% d ", & pile [I] [0], & pile [I] [1], & pile [I] [2]); if (D> = W) {printf ("1 \ n"); continue;} for (int I = 1; I <= n; I ++) {for (int j = 1; j <= I; j ++) {dis [j] [I] = dis [I] [j] = GetDis (pile [I] [0], pile [I] [1], pile [j] [0], pile [j] [1]);} int left = 1, right = m + n + 1; int ans = m + 1 + n; while (left <= right) {int mid = (left + right)/2; if (mid <= 0) break; build (n, m, mid-1, D, W); int t = dinic (2 * n * (mid-1) + 2, 0, 2 * n * (mid-1) + 2); if (t = m) right = mid-1, ans = mid; else left = mid + 1 ;} if (ans <= m + n) printf ("% d \ n", ans); else printf ("IMPOSSIBLE \ n") ;}return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.