bzoj 2330 SCOI2011糖果 查分约束系统

就根据题目中给的约束条件建图就行了

需要注意的是,我们要做的是最长路,因为需要约束每个点都是大于0

那么可以建一个超级源指向所有点,超级源的dis是1,边长为0

那么这样做最长路就可以了

好了我们这么写完了,之后发现re了,然后改大了点数组发现tle了。。。。

然后我也不知道怎么改,超级源连接所有点的时候,是for i:=1 to n do 的,这

样建完图之后,再做spfa相当于直接将n-1的点放入队列中,然后我改了下

连接的时候for i:=n downto 1 do 那么相当于将1-n放入队列中,然后这样就A了,

但是内存太大(之前RE开的),后来干脆把超级源去掉,直接将1-n放入队列,就可以直接A了

PS:最后的ans要用int64也就是longlong存,因为人太多了是吧。。。。

    内个大神能告诉我下为啥1-n放入队列就行,n-1就不行,求教。。。orz

 

/**************************************************************
    Problem: 2330
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:500 ms
    Memory:7744 kb
****************************************************************/
 
//By BLADEVIL
var
    n, k                        :longint;
    pre, other, len             :array[0..200010] of longint;
    last                        :array[0..100010] of longint;
    l                           :longint;
    que                         :array[0..1000010] of longint;
    dis                         :array[0..100010] of longint;
    flag                        :array[0..100010] of boolean;
    count                       :array[0..100010] of longint;
     
procedure connect(x,y,z:longint);
begin
    inc(l);
    pre[l]:=last[x];
    last[x]:=l;
    other[l]:=y;
    len[l]:=z;
end;
     
procedure init;
var
    i                           :longint;
    x, a, b                     :longint;
begin
    read(n,k);
    for i:=1 to k do
    begin
        read(x,a,b);
        if(not odd(x)) and (a=b) then
        begin
            writeln(-1);
            halt;
        end;
        case x of
            1:
            begin
                connect(a,b,0);
                connect(b,a,0);
            end;
            2:connect(a,b,1);
            3:connect(b,a,0);
            4:connect(b,a,1);
            5:connect(a,b,0);
        end;
    end;
end;
 
procedure main;
var
    h, t                        :longint;
    q, p                        :longint;
    cur                         :longint;
    ans                         :int64;
    i                           :longint;
     
begin
    fillchar(count,sizeof(count),0);
    h:=0; t:=n;
    for i:=1 to n do
    begin
        que[i]:=i;
        flag[i]:=true;
        dis[i]:=1;
    end;
    while h<>t do
    begin
        h:=h mod 1000000+1;
        cur:=que[h];
        flag[cur]:=false;
        q:=last[cur];
        while q<>0 do
        begin
            p:=other[q];
            if dis[cur]+len[q]>dis[p] then
            begin
                dis[p]:=dis[cur]+len[q];
                if not flag[p] then
                begin
                    inc(count[p]);
                    if count[p]>n then
                    begin
                        writeln(-1);
                        exit;
                    end;
                    t:=t mod 1000000+1;
                    que[t]:=p;
                    flag[p]:=true;
                end;
            end;
            q:=pre[q];
        end;
    end;
    ans:=0;
    for i:=1 to n do ans:=ans+dis[i];
    writeln(ans);
end;
 
begin
    init;
    main;
end.

 

posted on 2013-12-09 08:22  BLADEVIL  阅读(966)  评论(0编辑  收藏  举报