间谍网络

算最小编号时的更优做法是以cost<>maxlongint为起点再进行一次tarjan,未被搜到的(dfn=0)即不能被收买的间谍

 

搜到附代码:

var n,m,i,ii,u,v,j,k,l,x,y,a,b,tot,num,top,co,p,ans,anss:longint;
head,next,vet,color,st,dfn,low,cost,pay,d,minn:array[0..10005] of longint;
bb:boolean;

function min(a,b:longint):longint;
begin if A>b then exit(B);exit(A);end;

procedure tarjan(x:longint);
var i,v:longint;
begin
inc(num);low[x]:=num;dfn[x]:=num;
inc(top);st[top]:=x;
i:=head[x];
while i<>0 do begin
    v:=vet[i];
    if dfn[v]=0 then begin
        tarjan(v);
        low[x]:=min(low[x],low[v]);
        end
    else if color[v]=0 then low[x]:=min(low[x],dfn[v]);
        i:=next[i];
    end;
if dfn[x]=low[x] then begin
    inc(co);cost[co]:=maxlongint;
    while st[top]<>x do begin
        if st[top]<minn[co] then minn[co]:=st[top];
        color[st[top]]:=co;
        cost[co]:=min(cost[co],pay[st[top]]);
        dec(top);
        end;
    if st[top]<minn[co] then minn[co]:=st[top];
    color[st[top]]:=co;
    cost[co]:=min(cost[co],pay[st[top]]);
    dec(top);
    end;
end;


begin
readln(n);
readln(p);
for i:=1 to n do begin pay[i]:=maxlongint;minn[i]:=maxlongint;end;
for i:=1 to p do begin readln(x,y);pay[x]:=y;end;
readln(m);
for i:=1 to m do begin readln(x,y);
    inc(tot);
    next[tot]:=head[x];
    head[x]:=tot;
    vet[tot]:=y;
    end;
for i:=1 to n do
    if dfn[i]=0 then tarjan(i);
for i:=1 to n do begin
    ii:=head[i];
    while ii<>0 do begin
        v:=vet[ii];
        if color[v]<>color[i] then begin inc(d[color[v]]);
        if cost[color[i]]<>maxlongint then cost[color[v]]:=cost[color[i]];
        end;
        ii:=next[ii];
        end;
    end;
for i:=1 to n do begin
    ii:=head[i];
    while ii<>0 do begin
        v:=vet[ii];
        if color[v]<>color[i] then begin// inc(d[color[v]]);
        if cost[color[i]]<>maxlongint then cost[color[v]]:=cost[color[i]];
        end;
        ii:=next[ii];
        end;
    end;
//for i:=1 to co do write(minn[i],' ');writeln;
//for i:=1 to co do write(cost[i],' ');writeln;
bb:=false;anss:=maxlongint;
for i:=1 to co do if d[i]=0 then if cost[i]=maxlongint then bb:=true else ans:=ans+cost[i];
if bb then begin writeln('NO');
for i:=1 to co do if cost[i]=maxlongint then anss:=min(anss,minn[i]);
    writeln(anss);
    end
else begin
     writeln('YES');
     writeln(ans);
    end;
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值