"BZOJ1937" [shoi2004]mst minimum Spanning tree description
Input
The first behavior, N, M, which represents the number of vertices, represents the number of edges. The vertices are numbered 1, 2, 3 、......、 N-1, N. The next M-line, with three integers per line, indicates that there is an edge between the vertex UI and Vi, with a weight of Wi ui,vi,wi. All edges will appear in the input and will only occur once. Then the N-1 line, two integers per line, xi, Yi, indicates that the edge between the Vertex Xi and Yi is an edge of T.
Output
Output minimum weight value
Sample Input6 9
1 2 2
1 3 2
2 3 3
3 4 3
1 5 1
2 6 3
4 5 4
4 6 7
5 6 6
1 3
2 3
3 4
4 5
4 6
Sample Output8
"Sample description"
The right of the Edge (4,6) is changed from 7 to 3 at a cost of 4
The right of the edge is changed from 2 to 3, at a cost of 1.
The right of the edge (1,5) is changed from 1 to 4 at a cost of 3
So the total cost is 4+1+3=8.
Modification scenarios are not unique. HINT
1<=n<=50,1<=m<=800,1<=wi<=1000
N--> points: m--> Number of sides: WI---> Benquan
Problem Solving: Divine question ~
Obviously, the weight of the tree edge must be reduced, non-tree edge weights must increase, so if the non-tree edge J covered the tree edge I, there is wj+dj>=wi-di, that is, DI+DJ>=WI-WJ. So this ... TM is the top mark in the KM algorithm?
A review of the KM principle, KM algorithm is always satisfied: For each Edge a-b,l (a) +l (b) >=v (A, a), and all L (a) +l (b) =v (A, a) are composed of a sub-graph called equal sub-graph. and continuously adjust the calibration under the above conditions, so that the equal sub-graph is enlarged.
And for the subject, let WI-WJ is the edge right, and then find the best match is both the answer.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace Std;int n,m,cnt,nm,ans;int Map[60][60],pa[810],pb[810],pc[810],to[110],next[110],val[110],head[60],len[60];int FA [60],dep[60],bel[60],la[60],lb[810],va[60],vb[810],from[810],v[60][810];inline void Add (int a,int b,int c) {To[Cnt]= b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;} inline Int rd () {int Ret=0,f=1;char gc=getchar (); while (gc< ' 0 ' | | Gc> ' 9 ') {if (gc== '-') F=-f;gc=getchar ();} while (gc>= ' 0 ' &&gc<= ' 9 ') ret=ret*10+gc-' 0 ', Gc=getchar (); return ret*f;} void Dfs (int x) {for (int i=head[x];i!=-1;i=next[i]) if (to[i]!=fa[x]) fa[to[i]]=x,dep[to[i]]=dep[x]+1,bel[to[i]]=val[ I],dfs (To[i]);} void build (int a,int b,int c) {if (Dep[a]<dep[b]) swap (A, b), while (Dep[a]>dep[b]) V[bel[a]][nm]=max (0,len[bel[a]] -c), A=fa[a];while (a!=b) V[bel[a]][nm]=max (0,len[bel[a]]-c), V[bel[b]][nm]=max (0,LEN[BEL[B]]-C), a=fa[a],b=fa[b];} int dfs (int x) {va[x]=1;for (int y=1;y<=nm;y++) if (!vb[y]&&la[x]+lb[y]==v[x][y]) {vb[y]=1;if (!from[y]| | DFS (From[y])) {From[y]=x;return 1;}} return 0;} int main () {n=rd (), M=RD (), int i,j,k,a,b;memset (head,-1,sizeof (Head)), for (i=1;i<=m;i++) pa[i]=rd (), Pb[i]=rd (), PC [I]=rd (), Map[pa[i]][pb[i]]=map[pb[i]][pa[i]]=i;for (i=1;i<n;i++) {a=rd (), B=rd (), add (A,b,i), add (b,a,i), len[i]= pc[map[a][b]],map[a][b]=map[b][a]=0;} Dep[1]=1,dfs (1); for (i=1;i<=m;i++) if (Map[pa[i]][pb[i]]) {nm++;build (pa[i],pb[i],pc[i]);} for (i=1;i<=n;i++) for (j=1;j<=nm;j++) La[i]=max (La[i],v[i][j]), for (i=1;i<=n;i++) {while (1) {memset (va,0, sizeof (VA)), memset (Vb,0,sizeof (VB)), if (Dfs (i)) Break;int tmp=1<<30;for (j=1;j<=n;j++) if (Va[j]) for (k=1;k <=nm;k++) if (!vb[k]) tmp=min (Tmp,la[j]+lb[k]-v[j][k]), if (tmp==1<<30) break;for (j=1;j<=n;j++) if (Va[j]) La[j]-=tmp;for (j=1;j<=nm;j++) if (vb[j]) lb[j]+=tmp;}} for (i=1;i<=n;i++) ans+=la[i];for (i=1;i<=nm;i++) ans+=lb[i];p rintf ("%d", ans); return 0;}
"BZOJ1937" [shoi2004]mst minimum spanning tree km algorithm (linear programming)