由于数据比较水,就打了许多冗余,也由于这道题比较纠结,也不想再改了,将就看着吧 const maxn=100; max=1073741819; inf='shopping.in'; ouf='shopping.out'; anf='shopping1.out'; var n,m,s2,s:longint; ans1,ans2:real; v,cle:array[0..maxn]of boolean; b,c,b1,c1:array[0..maxn,0..maxn]of longint; cost,cost1:array[0..maxn,0..maxn]of real; st,pre,num,visit,pre1:array[0..maxn]of longint; min:array[0..maxn]of real; function dfs(x:longint;var z:boolean):longint; var i,j,ne,na:longint; cos:real; begin if x=s then begin dfs:=0;exit end; dfs:=0;visit[x]:=1; if visit[pre[x]]=2 then begin visit[x]:=2;exit end; if (visit[pre[x]]=1) then begin dfs:=pre[x];z:=true;cle[x]:=false;v[x]:=false;ans1:=ans1+cost[pre[x],x]; inc(s2);st[s2]:=x;visit[x]:=2;exit end; if visit[pre[x]]=0 then dfs:=dfs(pre[x],z); visit[x]:=2; if dfs=-1 then exit; if dfs=0 then begin{ ans1:=ans1+cost[pre[x],x];cle[x]:=false; }exit end; v[x]:=false; if x<>dfs then begin inc(s2);st[s2]:=x;cle[x]:=false;ans1:=ans1+cost[pre[x],x];exit end; i:=1;ans1:=ans1+cost[pre[x],x];inc(s2);st[s2]:=x; c1:=c;b1:=b;pre1:=pre;cost1:=cost; while i<=s2 do begin ne:=st[i]; for j:=1 to b[ne,0] do if (v[b[ne,j]])and(cle[b[ne,j]]) then begin na:=b[ne,j]; if cost1[x,na]>max then begin inc(b1[x,0]);b1[x,b1[x,0]]:=na;inc(c1[na,0]);c1[na,c1[na,0]]:=x end; if cost[ne,na]<cost1[x,na] then cost1[x,na]:=cost[ne,na]; if (cost[ne,na]<cost1[pre1[na],na])or(not cle[pre1[na]]) then pre1[na]:=x end; for j:=1 to c[ne,0] do if (v[c[ne,j]])and(cle[c[ne,j]]) then begin na:=c[ne,j]; if cost[na,x]>max then begin inc(b1[na,0]);b1[na,b1[na,0]]:=x;inc(c1[x,0]);c1[x,c1[x,0]]:=na end; cos:=cost[na,ne]-cost[pre[ne],ne]; if cos<cost1[na,x] then cost1[na,x]:=cos; if (cos<cost1[pre1[x],x])or(not cle[pre1[x]]) then pre1[x]:=na end; inc(i) end; b:=b1;c:=c1;pre:=pre1;cost:=cost1;dfs:=-1 end; procedure dfs2(x:longint); begin if x=0 then exit; visit[x]:=1; if visit[pre[x]]=0 then dfs2(pre[x]); visit[x]:=2;cle[x]:=false; ans1:=ans1+cost[pre[x],x]; end; procedure getans; var i:longint; begin fillchar(visit,sizeof(visit),0); for i:=1 to n do if (cle[i])and(visit[i]=0) then dfs2(i) end; procedure mintree; var z:boolean; i:longint; begin z:=false; fillchar(visit,sizeof(visit),0); fillchar(v,sizeof(v),true); fillchar(st,sizeof(st),0);s2:=0; for i:=1 to n do if (cle[i])and(visit[i]=0) then if dfs(i,z)<>0 then break; if z then mintree else getans end; procedure origin; var i:longint; begin for i:=1 to n do begin pre[i]:=n+1;cost[pre[i],i]:=max end; fillchar(cle,sizeof(cle),true); fillchar(cost,sizeof(cost),127); ans1:=0;ans2:=0; fillchar(min,sizeof(min),127); fillchar(c,sizeof(c),0);fillchar(b,sizeof(b),0); end; procedure init; var i,x,y:longint; xx,z:real; begin assign(input,inf);reset(input); readln(n); origin; s:=0; for i:=1 to n do begin readln(xx,y); num[i]:=y; if y>0 then begin inc(b[s,0]);b[s,b[s,0]]:=i;cost[s,i]:=xx; inc(c[i,0]);c[i,c[i,0]]:=s; if cost[s,i]<cost[pre[i],i] then pre[i]:=s; if xx<min[i] then min[i]:=xx end else cle[i]:=false end; readln(m); for i:=1 to m do begin readln(x,y,z); if (num[x]>0)and(num[y]>0) then begin inc(b[x,0]);b[x,b[x,0]]:=y;cost[x,y]:=z; inc(c[y,0]);c[y,c[y,0]]:=x; if cost[x,y]<cost[pre[y],y] then pre[y]:=x; if z<min[y] then min[y]:=z end end; for i:=1 to n do if num[i]>0 then ans2:=ans2+(num[i]-1)*min[i]; mintree; assign(output,ouf);rewrite(output); writeln(ans1+ans2:0:2); close(output); close(input) end; begin init end.