Cod sursa(job #82454)

Utilizator gurneySachelarie Bogdan gurney Data 6 septembrie 2007 23:31:34
Problema Critice Scor 70
Compilator fpc Status done
Runda Arhiva de probleme Marime 4.11 kb
program critice;
  const
    fin='critice.in';
    fout='critice.out';
    nmax=1010;
    mmax=20020;
    inf=maxlongint shr 1;
type
  Tedge=record
      start,target:integer;
      capa,flow:longint;
      prev:integer;
    end;
  int=array[1..nmax] of integer;
  lint=array[1..nmax] of longint;
  tlint=^lint;
  tinteger=^int;
var
  edge:array[1..mmax] of Tedge;
  last,pred,q:tinteger;
  used:array[1..nmax] of boolean;
  delta:tlint;
  aux:tedge;
  pop,push,m,ii,cur,i,j,k,n,x,y,c,nedge:longint;
  tflow:longint;
  critic:array[1..nmax] of boolean;
  num:longint;


procedure insert(x,y,c:longint);
  begin
    inc(nedge);
    with edge[nedge] do
      begin
        start:=x;target:=y;
        capa:=c;flow:=0;
        prev:=last^[x];
        last^[x]:=nedge;
      end;
    inc(nedge);
    with edge[nedge] do
      begin
        start:=y;target:=x;
        capa:=c;flow:=0;
        prev:=last^[y];
        last^[y]:=nedge;
      end;
  end;

function op(n:integer):integer;
  begin
    if n and 1=1 then
      op:=n+1
    else
      op:=n-1;
  end;

begin
  new(last);new(pred);new(q);new(delta);
  assign(input,fin);
    reset(input);
    readln(n,m);
    nedge:=0;
    for i:=1 to m do
      begin
        readln(x,y,c);
        insert(x,y,c);
      end;
  close(input);
  assign(output,fout);
    rewrite(output);
    tflow:=0;
    while true do
      begin
        pop:=1;push:=2;
        q^[1]:=1;
        fillchar(used,sizeof(used),false);
        delta^[1]:=inf;
        used[1]:=true;
        cur:=1;
        while pop<push do
          begin
            x:=last^[q^[pop]];
            while x>0 do
              with edge[x] do
                begin
                  if (abs(flow)<capa) and (not(used[target])) then
                    begin
                      used[target]:=true;
                      q^[push]:=target;
                      inc(push);
                      pred^[target]:=x;
                      delta^[target]:=delta^[start];
                      if delta^[target]>capa-flow then
                        delta^[target]:=capa-flow;
                      if used[n] then
                        break;
                    end;
                  x:=prev;
                end;
            inc(pop);
          end;
            if not(used[n]) then
              break;
            cur:=n;
            x:=delta^[n];
            inc(tflow,delta^[n]);
            repeat
              x:=pred^[cur];
              with edge[x] do
                begin
                  inc(flow,delta^[n]);
                  y:=op(x);
                  edge[y].flow:=edge[y].flow-delta^[n];
                  cur:=start;
                end;
            until cur=1;
      end;
    fillchar(used,sizeof(used),false);
    q^[1]:=1;pop:=1;push:=2;used[1]:=true;
    critic[1]:=true;
    while pop<push do
      begin
        cur:=q^[pop];
        inc(pop);
        x:=last^[cur];
        while x>0 do
          with edge[x] do
            begin
              if (abs(flow)<capa) and (not(used[target])) then
                begin
                  used[target]:=true;
                  q^[push]:=target;
                  inc(push);
                  critic[target]:=true;
                end;
              x:=prev;
            end;
      end;
    fillchar(used,sizeof(used),false);
    q^[1]:=n;pop:=1;push:=2;used[n]:=true;
    while pop<push do
      begin
        cur:=q^[pop];
        inc(pop);
        x:=last^[cur];
        while x>0 do
          with edge[x] do
            begin
              if (abs(flow)<capa) and (not(used[target])) then
                begin
                  used[target]:=true;
                  q^[push]:=target;
                  inc(push);
                end;
              x:=prev;
            end;
      end;
    num:=0;
    for i:=1 to nedge do
      if (critic[edge[i].start])and (used[edge[i].target]) then
        inc(num);
    writeln(num);
    for i:=1 to nedge do
      if (critic[edge[i].start])and (used[edge[i].target]) then
        writeln((i+1)shr 1);
  close(output);
end.