IOI-2003-Maintain

来源:互联网 发布:守望先锋优化太差 编辑:程序博客网 时间:2024/05/19 08:45

[描述]:
在一个初始化为空的无向图中,不断加入新边。如果当前图连通,就求出当前图最小生成树的总权值;否则,输出-1

[分析]:
通过并查集判断连通性,若当前边的两端点已连通,则在这条环上找最大的一条边删去。
[代码]:

program maintain;var   father:array[1..200] of longint;   g:array[1..200,1..200] of longint;   N,M,Len_count,Cost,i,S,T,L:longint;      q:array[0..200] of longint; top,last:longint;   pre:array[1..200] of longint;   v:array[1..200] of boolean;function f(x:longint):longint;begin     if father[x]=0 then exit(x)     else begin          father[x]:=f(father[x]);          exit(father[x]);     end;end;procedure Sift(S,T,L:longint);var   Max,SS,TT,i,j:longint;begin     fillchar(v,sizeof(v),false);     top:=0; last:=1; q[1]:=S; v[s]:=true;     while (top<last)and(not v[T]) do begin           inc(top);           i:=q[top];           for j:=1 to N do               if (not v[j])and(g[i,j]>0) then begin                  v[j]:=true;                  pre[j]:=i;                  inc(last);                  q[last]:=j;               end;     end;     i:=T; Max:=0;     while i<>S do begin           if g[pre[i],i]>Max then begin              Max:=g[pre[i],i];              SS:=pre[i];              TT:=i;           end;           i:=pre[i];     end;     if Max>L then begin        g[SS,TT]:=0;        g[TT,SS]:=0;        g[S,T]:=L;        g[T,S]:=L;        dec(Cost,Max);        inc(Cost,L);     end;     end;begin     assign(input,'maintain.in');     assign(output,'maintain.out');     reset(input);     rewrite(output);     fillchar(father,sizeof(father),0);     fillchar(g,sizeof(g),0);     Len_count:=0;     Cost:=0;     readln(N,M);     for i:=1 to M do begin         readln(S,T,L);         if f(S)<>f(T) then begin            father[f(S)]:=f(T);            g[S,T]:=L;            g[T,S]:=L;            inc(Len_count);            inc(Cost,L);         end else Sift(S,T,L);                  if Len_count=N-1 then            writeln(Cost)         else writeln(-1);                  {         Writeln(#32#32#32,'Debug:');         Writeln(#32#32#32,'LenCount:',Len_count);         for j:=1 to N-1 do         for k:=j+1 to N do             if g[j,k]<>0 then                Writeln(#32#32#32,'g[',j,',',k,']:=',g[j,k]);         }     end;          close(input);     close(output);end.

原创粉丝点击