Sgu_206
I have to say that the idea of this topic is so strange that I still cannot understand it for a while ......
The first greedy idea is that D [I] of shizilu must be smaller than or equal to C [I, instead, d [J] of shizi road must be greater than or equal to C [J, if we use X [I] to describe the increment of Ishigaki's false positive, then X [I] = C [I]-d [I], if we use y [J] to describe the increment of non-shizi road lie reports, Y [J] = d [J]-C [J], the final goal is to find the minimum value of sum {x [I]} + sum {Y [J.
Next, consider the important conditions given in the question, that is, to create a minimum spanning tree for the shizi road, a ring will be formed when any non-shizi road is added to the Minimum Spanning Tree, if this non-stone Road D [J] is smaller than the d [I] of a stone road on the ring, this non-stone road can replace the stone road to become the edge of the smallest generation tree, this is in conflict with the assumption that the "shizi road forms the smallest Spanning Tree". Therefore, for any shizi Road on the ring, there is d [J]> = d [I].
Now all the conditions have been analyzed. It seems a headache at first glance, because we need to determine the minimum value of sum {x [I]} + sum {Y [J]} based on these inequalities, we may need to use linear programming, at least now I don't plan linearly ...... However, if we deform the original inequality, it would be amazing to hook the km ......
From d [J]> = d [I], we can obtain y [J] + C [J]> = C [I]-X [I], after moving the X [I] and X [J] variables to one side, we get X [I] + Y [J]> = C [I]-C [J], this formula is very similar to a [I] + B [J]> = G [I] [J] In km. The process of solving km is actually on the premise that all a [I] + B [J]> = G [I] [J] are met, scale down a [I]. When a [I] + B [J] = G [I] [J] appears, A match is completed, so after completing the km, the sum {A [I]} + sum {B [J]} value is actually minimized.
In this way, the idea of this question will be available, find all the relationships between D [J]> = d [I] and convert them into a relationship like x [I] + Y [J]> = C [I]-C [J ]., then the weight for connecting an I to J is the c [I]-C [J] edge. If the points on both sides are different, the points on both sides are equal, and then the sides are completed, the weight of the completed edge is regarded as 0, after completing the km operation, you can calculate the values of d [I] And d [J] based on the values of a [I] and B [J. When creating a graph, if C [I]-C [J] <0, you can directly regard this edge as 0, because the increment is positive, therefore, an implicit condition X [I] + Y [J]> = 0.
# Include <stdio. h> # Include < String . H> # Include <Algorithm># Define Maxn 70 # Define Maxd 410 # Define Maxm 810 # Define INF 0x3f3f3f Int N, m, D, first [maxn], E, next [maxm], V [maxm], W [maxm], C [maxm]; Int G [maxd] [maxd], visx [maxd], visy [maxd], a [maxd], B [maxd], slack, ym [maxd]; Void Add ( Int X, Int Y, Int Z) {v [E] = Y, W [e] = Z; next [E] = First [X], first [x] = e ++ ;} Int DFS ( Int Cur, Int Fa, Int T, Int ID, Int Value ){ Int I; If (Cur = T) Return 1 ; For (I = first [cur]; I! =- 1 ; I = Next [I]) If (V [I]! = Fa && DFS (V [I], cur, T, ID, value) {G [I / 2 ] [ID] = STD: max (G [I/ 2 ] [ID], W [I]- Value ); Return 1 ;} Return 0 ;} Void Init (){ Int I, x, y, z; n -= 1 ; Memset (first, - 1 , Sizeof (First), E = 0 ; For (I = 0 ; I <n; I ++) {Scanf ( " % D " , & X, & Y ,& Z); add (x, y, z), add (Y, x, z);} memset (G, 0 , Sizeof (G); m -= N; For (I = 0 ; I <m; I ++ ) {Scanf ( " % D " , & X, & Y, & Z), C [I] = Z; DFS (X, - 1 , Y, I, Z );}} Int Searchpath ( Int Cur, Int N ){ Int I; visx [cur] = 1 ; For (I = 0 ; I <n; I ++) If (! Visy [I]) { Int T = A [cur] + B [I]- G [cur] [I]; If (T = 0 ) {Visy [I] = 1 ; If (Ym [I] =- 1 | Searchpath (ym [I], n) {ym [I] = Cur; Return 1 ;}} Else Slack = STD: min (slack, T );} Return 0 ;} Void Solve (){ Int I, j, n = STD: max (n, m); memset (B, 0 , Sizeof (B [ 0 ]) * N ); For (I = 0 ; I <n; I ++ ) For (J = A [I] = 0 ; J <n; j ++) A [I] = STD: max (A [I], G [I] [J]); memset (ym, - 1 , Sizeof (Ym [ 0 ]) *N ); For (I = 0 ; I <n; I ++ ) For (;) {Slack = INF; memset (visx, 0 , Sizeof (Visx [ 0 ]) * N); memset (visy, 0 , Sizeof (Visy [0 ]) * N ); If (Searchpath (I, n )) Break ; For (J = 0 ; J <n; j ++) If (Visx [J]) A [J]-= Slack; For (J = 0 ; J <n; j ++) If (Visy [J]) B [J] + = Slack ;} For (I = 0 ; I <n; I ++ ) Printf ( " % D \ n " ,-A [I] + W [I < 1 ]); For (I = 0 ; I <m; I ++ ) Printf ( " % D \ n " , B [I] + C [I]);} Int Main (){ While (Scanf ( " % D " , & N, & M) = 2 ) {Init (); solve ();} Return 0 ;}