Test instructions
An undirected connected graph is given, and one of the spanning trees is specified;
Each edge has a weight of Vali, if the increase of the weight of 1 to spend the AI, reduce the cost of 1 bi;
Now to make the specified spanning tree a minimum spanning tree, the minimum cost is calculated;
n<=300,m<=1000;
Exercises
A linear programming comparison of God's topic, brush in front of the comparison of the water will not brush;
First there is a very obvious thing (I did not see it), the edge of the tree must reduce the weight, not the edge of the tree must increase the weight value;
Then consider for a spanning tree to be the minimum to meet the conditions, that is, the constraint conditions of the subject;
Like the Tarjan algorithm, each non-tree edge generates a ring on the tree;
And if some edge of the ring is larger than it, then the ring can be disconnected from that edge, and the spanning tree is smaller;
In other words, for a non-tree edge, the top of the ring is less than equal to it;
Find the process of constraint I write seems rather stupid, deep search to remember a bunch of re-LCA;
But in any case the worst but n*m will not be so tle;
Set XI as the first edge of the change amount, then the edge of the tree is the amount of reduction, non-tree edge for the increase of a large number;
Available equation: Vali+xi<=valj-xj (i is a tree edge J is not a tree edge, and i,j on a ring);
Move Item:xi+xj<=valj-vali;
The current linear programming is:
Min∑costi*xi
Xi+xj<=valj-vali
Obviously it does not exist the basic feasible solution, then does some deformation;
First, the target function is reversed:
Max∑-costi*xi
Xi+xj<=valj-vali
Then the dual principle!
Max∑ (Valj-vali) *x (j,i)
%*&^%*>=-costi
And then the inequality variable number:
Max∑ (Valj-vali) *x (j,i)
-%*&^%*<=costi
Now it can be found that the linear programming is already the standard type;
And the cost in the title is positive, that is, the linear programming has a basic feasible solution;
Then on the simple type directly engage in this thing, the nature of the topic also guarantees that this thing will not be unbounded;
Time complexity O (Simple Type (n*m,m));
Obviously it will be T-dead, but the constraints will not have the worst case n*m so much.
So it can still be n*m, the array of the open to 4000 can A;
Code:
#include <vector> #include <math.h> #include <stdio.h> #include <string.h> #include < Algorithm> #define N 310 #define M 1100 using namespace std; Const double EPS = 1e-8; Const double INF = 1e100; struct Node {int n, m; Double a[m][m << 2], b[m], c[m << 2], V; int find () {for (int i = 1; I <= n; i++) {if (C[i] > EPS) return i ; } return 0; } void Rotate (int l, int e) {b[l]/= a[l][e]; for (int i = 1; I <= n; i++) {if (i! = e) a[l][i]/= a[l][e]; } A[l][e] = 1/a[l][e]; for (int i = 1; I <= m; i++) {if (i = = L | | fabs (a[i][e]) < EPS) continue; B[i]-= b[l] * A[i][e]; for (int j = 1; J <= N; j + +) {if (j! = e) a[i][j]-= a[l][j] * A[i][e] ; } A[i][e] *=-a[l][e]; } v + = c[e] * B[l]; for (int i = 1; I <= n; i++) {if (i! = e) c[i]-= c[e] * A[l][i]; } C[e] *=-a[l][e]; } void Simplex () {int I, j, K, L, E; while (E = find ()) {double Lim = INF; for (i = 1; I <= m; i++) {if (A[i][e] < EPS) continue; if (Lim>b[i]/a[i][e]) Lim = B[i]/a[i][e], L = i; } Rotate (L, E); }}}t; Vector<int>to[n], Val[n], cost[n], no[n]; vector<bool>cov[n]; int fa[n], prec[n], prev[n], preno[n], tim[n], deep[n], tot; void Build (int x, int y, int val, int no) {if (Deep[x] < deep[y]) swap (x, y); while (Deep[x]>deep[y]) {T.C[++T.N] =-(val-prev[x]); T.A[NO][T.N] = 1; T.A[PRENO[X]][T.N] = 1; x = Fa[x]; } while (x! = y) {T.C[++T.N] =-(val-prev[x]); T.A[NO][T.N] = 1; T.A[PRENO[X]][T.N] = 1; x = Fa[x]; T.C[++T.N] =-(val-prev[y]); T.A[NO][T.N] = 1; T.A[PRENO[Y]][T.N] = 1; y = fa[y]; }} void Dfs (int x, int pre, int v, int num, int d) {int i, y; Fa[x]=pre,prev[x] = V, preno[x] = num, tim[x] = ++tot, deep[x] = D; for (i = 0; i < to[x].size (); i++) {if (cov[x][i]&& (Y=to[x][i])!=pre) Dfs (y, x, val[x) [i], no[x][i], D + 1); } for (i = 0; i < to[x].size (); i++) {if (!cov[x][i] && tim[y = to[x][i]] && Tim[y] &l T Tim[x]) {Build (x, Y, Val[x][i], no[x][i]); }}} int main () {int n, m, I, J, K, X, Y, V, F, a, B; scanf ("%d%d", &n, &m); for (i = 1; I <= m; i++) {scanf ("%d%d%d%d%d%d", &x, &y, &v, &f, &a, &b); To[x].push_back (y), Val[x].push_back (v), Cov[x].push_back (f), No[x].push_back (i); To[y].push_back (x), Val[y].push_back (v), Cov[y].push_back (f), No[y].push_back (i); if (f) t.b[i] = b; else t.b[i] = A; } DFS (1, 0, 0, 0, 1); T.m=m; T.simplex (); printf ("%.0LF", T.V); return 0; }
bzoj-3118 Orz the MST