2014 Xiangtan national invitational competition I question intervals/poj 3680/obtain the right range under the limited number of times to maximize the right/small problem (cost flow)

Source: Internet
Author: User
Tags getv

Let's talk about poj3680: give n permissions (<10 W) an interval (n <200). (The interval can be up to 10 W) ensure that the total and output weights are the largest if the number of data records on the number axis is overwritten for a maximum of K times.

Thought: Restricted processing: s --> the starting traffic is K, and the total permission is required to be the largest, that is, the maximum cost. Therefore, the cost is negative, and the minimum cost is the maximum flow. For the input range [a, B]: W, add edge: A --> B, the traffic is 1, and the fee is-w.

For vertex I, I + 1, add edge, the cost is 0, the traffic is infinite. Obviously, this processing restricts the maximum number of times in a range (Traffic Control). The maximum flow can be taken along the added edge as much as possible, and the larger the number, the better (negative number is just the minimum cost ), satisfying the question. But TLE, because w to 10 W, and the side is 10 W, it will inevitably time out, so the point must be processed. All points are "COMPRESSED" and pushed forward, as long as there are points, the previous one can be connected to the backend. For details, see the code.


Let's look at this question in Xiangtan: the opposite: give n users the right to open a range (n <2000) (up to 9 times of 10 ), ensure that when the range [1-, m] is overwritten at least K times, the total weight is required to be minimized, and the output weight is the smallest.

Idea: (thanks to the graph creation prompt of zz1215) Handling of restrictions: it is clear that the traffic at the exit must reach K. For the input range [a, B]: W, add edge: A --> B, the traffic is 1, and the cost is W. However, in this case, the points are discrete, there is no continuity at all,

It is impossible to create a graph like the above question (otherwise the cost is 0), so: in this way: point I is connected to the previous vertex, the cost is 0, the traffic is infinite, this cleverly solves the discrete point problem. The minimum cost is enough. Obviously, we need to handle the problem.


# Include <iostream> # include <queue> # include <cstdio> using namespace STD; const int INF = 0x3f3f3f3f; const int T = 100000; int N, K; int e [300001] [4]; int head [100101]; int nume = 0; void inline Adde (int from, int to, int W, int C) {e [nume] [0] = to; E [nume] [1] = head [from]; head [from] = nume; E [nume] [2] = W; E [nume ++] [3] = C; E [nume] [0] = from; E [nume] [1] = head [to]; head [to] = nume; E [nume] [2] =-W; E [nume ++] [3] = 0 ;}int INQ [111005]; int d [110 000]; // spfabool spfa (Int & sumcost) // charge for each request {int pre [110005]; int minf = inf; int PRV [110005]; for (INT I = 0; I <= t + 1; I ++) {INQ [I] = 0; d [I] = inf ;} pre [0] =-1; PRV [0] =-1; // records the edge of point I and the point before I respectively in the path. (This is convenient if you use a matrix to create a graph) queue <int> q; q. Push (0); INQ [0] = 1; d [0] = 0; while (! Q. empty () {int cur = Q. front (); q. pop (); INQ [cur] = 0; For (INT I = head [cur]; I! =-1; I = E [I] [1]) {int v = E [I] [0]; if (E [I] [3]> 0 & E [I] [2] + d [cur] <D [v]) {d [v] = E [I] [2] + d [cur]; PRV [v] = cur; // record augmented path pre [v] = I; if (! INQ [v]) {q. push (V); INQ [v] = 1 ;}}} if (d [t + 1] = inf) return 0; // cannot be extended int cur = t + 1; // destination point while (cur! = 0) // obtain the minimum residual traffic edge on the path as the traffic augmented {minf = E [pre [cur] [3] <minf? E [pre [cur] [3]: minf; cur = PRV [cur];} cur = t + 1; while (cur! = 0) // augmented, changing traffic {e [pre [cur] [3]-= minf; E [pre [cur] ^ 1] [3] + = minf; cur = PRV [cur];} sumcost + = d [t + 1] * minf; // The fee is the unit fee (the sum of the traffic per edge in the path) * traffic return 1;} void mincost (Int & sumcost) {While (spfa (sumcost); // return;} int hash [100011]; void clear () {nume = 0; For (INT I = 0; I <= t + 1; I ++) {hash [I] = head [I] =-1 ;}} struct qujian {int A, B, W ;}; int main () {int t; scanf ("% d", & T); For (INT II = 1; II <= T; II ++) {clear (); CIN> N> K; int A, B, W; vector <qujian> QQ (N ); vector <int> V; For (INT I = 0; I <n; I ++) {scanf ("% d", & A, & B, & W); hash [a] = hash [B] = 1; QQ [I]. A = A; QQ [I]. B = B; QQ [I]. W = W; Adde (a, B,-W, 1) ;}for (INT I = 0; I <100010; I ++) // process the "existing" vertex if (hash [I] = 1) {v. push_back (I) ;}for (INT I = 0; I <v. size ()-1; I ++) // "existing" vertex edge {Adde (V [I], V [I + 1], 0, k );} ADDE (V [v. size ()-1], T, 0, k); // edge adde of the Super source sink point (0, V [0], 0, k); Adde (t, T +, K); int sumcost = 0; mincost (sumcost); cout <-sumcost <Endl; // reverse number} return 0 ;}


Xiangtan:

# Include <iostream> # include <queue> # include <algorithm> using namespace STD; const int INF = 0x3f3f3f3f; int N, K, M; int countv = 0; int f [4009]; void getf (int x) // compress the nine times from 1 to 10 (up to 4000 points) to less than 4000, one-to-one correspondence, so as to create a graph. {If (x> m) {f [countv] = x; return;} // It is useless if it is greater than m, which is equivalent to M. Countv ++; F [countv] = x;} int getv (int x) // obtain the corresponding vertex {If (x> = m) {return countv ;} for (INT I = 1; I <= countv; I ++) {If (F [I] = x) return I ;}} int e [20001] [4]; int head [4005]; int nume = 0; void inline Adde (int from, int to, int W, int C) {e [nume] [0] = to; E [nume] [1] = head [from]; head [from] = nume; E [nume] [2] = W; E [nume ++] [3] = C; E [nume] [0] = from; E [nume] [1] = head [to]; head [to] = nume; E [nume] [2] =-W; E [nume ++] [3] = 0 ;}int INQ [4005]; int d [400 5]; // spfabool spfa (Int & sumcost, Int & sumflow) // charge for each request {int pre [4005]; int minf = inf; int PRV [4005]; for (INT I = 0; I <= countv + 4; I ++) {INQ [I] = 0; d [I] = inf ;} pre [0] =-1; PRV [0] =-1; // records the edge of point I and the point before I respectively in the path. (This is convenient if you use a matrix to create a graph) queue <int> q; q. Push (0); INQ [0] = 1; d [0] = 0; while (! Q. empty () {int cur = Q. front (); q. pop (); INQ [cur] = 0; For (INT I = head [cur]; I! =-1; I = E [I] [1]) {int v = E [I] [0]; if (E [I] [3]> 0 & E [I] [2] + d [cur] <D [v]) {d [v] = E [I] [2] + d [cur]; PRV [v] = cur; // record augmented path pre [v] = I; if (! INQ [v]) {q. push (V); INQ [v] = 1 ;}}} if (d [countv + 1] = inf) return 0; // cannot be extended int cur = countv + 1; // destination point while (cur! = 0) // obtain the minimum residual traffic edge on the path as the traffic augmented {minf = E [pre [cur] [3] <minf? E [pre [cur] [3]: minf; cur = PRV [cur];} cur = countv + 1; while (cur! = 0) // augmented, changing traffic {e [pre [cur] [3]-= minf; E [pre [cur] ^ 1] [3] + = minf; cur = PRV [cur];} sumcost + = d [countv + 1] * minf; // The fee is the unit fee (the sum of the traffic per edge in the path) * traffic sumflow + = minf; return 1;} void mincost (Int & sumcost, Int & sumflow) {While (spfa (sumcost, sumflow )); // return;} void clear () {nume = countv = 0; For (INT I = 0; I <= 4003; I ++) {head [I] =-1; F [I] = 0 ;}} struct qujian {int A, B, W ;}; int main () {int T; cin> T; For (int ii = 1; II <= T; I I ++) {clear (); CIN> N> K> m; int A, B, W; vector <int> V; vector <qujian> QQ (n); For (INT I = 0; I <n; I ++) {CIN> A> B> W; V. push_back (a); V. push_back (B); QQ [I]. A = A; QQ [I]. B = B; QQ [I]. W = W;} Sort (v. begin (), V. end (); // processing point from small to large for (INT I = 0; I <v. size (); I ++) {getf (V [I]) ;}for (INT I = 0; I <n; I ++) {int T1 = getv (qq [I]. a); int t2 = getv (qq [I]. b); Adde (T1, T2, QQ [I]. w, 1); // Note: If the Adde (getv (A), getv (B), W, 1) parameter is used, it is assigned a value from right to left !!!} For (INT I = 1; I <countv; I ++) {Adde (I + 1, I, 0, INF); // note: if the Adde (getv (A), getv (B), W, 1) parameter is used, it is passed from right to left !!!} Adde (, 0, INF); Adde (countv, countv +, K); int sumcost = 0; int sumflow = 0; mincost (sumcost, sumflow ); cout <"case" <II <":"; if (sumflow! = K) // cannot reach K, no solution {cout <-1 <Endl;} else {cout <sumcost <Endl ;}} 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.