Test instructions
In some subjects, and remedial classes, each subject eventually required to be fixed to a certain level, you can spend a certain amount of money in the remedial class to a certain level, there is a limit when entering the remedial class, that is to achieve his given the subject and level restrictions, such as a B c D M means that subject a must reach the B level in order to spend m money to fix the subject C to the D level, and finally ask the minimum tuition cost to fix all the subjects to a given level.
Ideas:
we can think of each level of each subject as a point, and then according to the given relationship, the level and the level of the Bing between the establishment, and then the non-0 grade to build a current level-1 of the side, the cost is 0, meaning that the current level is fixed, the previous level is finished, and finally a point in the virtual , connect all levels 0 points, meaning that the beginning of the 0 grade has been repaired, and then the smallest tree diagram on the line, for the minimum graph, he is in fact is in the smallest generation of graphs, with the Chu-Liu algorithm (I do not know the algorithm, but directly sticky template only, I have never felt the correctness of this algorithm).
#include <stdio.h> #include <string.h>//******************************************Const INTMaxm=2000000;Number of edgesConst INTMaxn=25100;Number of pointsConst INTInf=0x3f3f3f3f; typedef struct {intU,V,W; }EDGE;EDGE E[Maxm]; intPre[Maxn],Id[Maxn],Vis[Maxn],Inch[Maxn]; typedef struct {intDirectedmst(intRoot, intN, intM) {0....n,m strips starting from 0intRes=0,Nv=N +1,I; while (1) {for (I=0;I<Nv;I++) {Inch[I]=Inf; } for (I=1;I<=M;I++) {intU=E[I].U; intV=E[I].V; if (E[I].W<Inch[V]&&U!=V) {Pre[V]=U;Inch[V]=E[I].W; }} for (I=0;I<Nv;I++) {if (I==Root) continue; if (Inch[I]==Inf) Return-1; } intCntnode=0;Memset(Id,-1, sizeof (Id[0])*(Nv+3));Memset(Vis,-1, sizeof (Vis[0])*(Nv+3));Inch[Root]=0; for (I=0;I<Nv;I++) {Res+=Inch[I]; intV=I; while (Vis[V]!=I&&Id[V]==-1&&V!=Root) {Vis[V]=I;V=Pre[V]; } if (V!=Root&&Id[V]==-1) {for (intU=Pre[V];U!=V;U=Pre[U]) {Id[U]=Cntnode; }Id[V]=Cntnode++; }} if (Cntnode==0) break; for (I=0;I<Nv;I++) {if (Id[I]==-1)Id[I]=Cntnode++; } for (I=1;I<=M;I++) {intV=E[I].V;E[I].U=Id[E[I].U];E[I].V=Id[E[I].V]; if (E[I].U!=E[I].V) {E[I].W-=Inch[V]; } }Nv=Cntnode;Root=Id[Root]; } returnRes; } }M_tree;//***************************************intSum[55]; intNum[55]; int main () {intN ,M ,I ,J; intA ,B ,C ,D ,Mo;M_tree T; while (~scanf("%d%d",&N,&M) &&N +M) {Sum[0] =0; for (I =1 ;I<=N ;I ++) {scanf("%d",&Num[I]);Num[I] ++;Sum[I] =Sum[I-1] +Num[I]; } intTt =0; while (M--) {scanf("%d%d%d%d%d",&A,&B,&C,&D,&Mo);B++ ,D ++; for (intI =Sum[A-1] +B ;I<=Sum[A] ;I ++) {E[++Tt].U =I;E[Tt].V =Sum[C-1] +D;E[Tt].W =Mo; }} for (I =1 ;I<=N ;I ++) {for (J =Sum[I-1] +2 ;J<=Sum[I] ;J ++) {E[++Tt].U =J;E[Tt].V =J-1;E[Tt].W =0; }E[++Tt].U =0;E[Tt].V =Sum[I-1] +1;E[Tt].W =0; }Printf("%d\n",T.Directedmst(0 ,Sum[N] ,Tt)); } return0; }