Cod sursa(job #82443)

Utilizator gurneySachelarie Bogdan gurney Data 6 septembrie 2007 22:40:01
Problema Critice Scor 60
Compilator fpc Status done
Runda Arhiva de probleme Marime 4.16 kb
program critice;
  const
    fin='critice.in';
    fout='critice.out';
    nmax=1000;
    mmax=20000;
    inf=maxlongint;
type
  Tedge=record
      start,target:longint;
      capa,flow:longint;
      prev:longint;
    end;
var
  edge:array[1..mmax] of Tedge;
  last:array[1..nmax] of longint;
  used:array[1..nmax] of boolean;
  delta,pred,q:array[1..nmax+10] of longint;
  aux:tedge;
  pop,push,m,ii,cur,i,j,k,n,x,y,c,nedge:longint;
  tflow:longint;
  critic:array[1..mmax] 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:longint):longint;
  begin
    if n and 1=1 then
      op:=n+1
    else
      op:=n-1;
  end;

begin
  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);
        fillchar(delta,sizeof(delta),0);
        delta[1]:=inf;
        used[1]:=true;
        cur:=1;
        while pop<push do
          begin
            cur:=q[pop];
            inc(pop);
            x:=last[cur];
            while x>0 do
              with edge[x] do
                begin
                  if (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;
          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]);
                  edge[op(x)].flow:=edge[op(x)].flow-delta[n];
                  cur:=start;
                end;
            until cur=1;
      end;
    num:=0;
    for ii:=1 to m do
      if (edge[ii shl 1-1].capa=edge[ii shl 1 -1].flow)or(edge[ii shl 1].capa=edge[ii shl 1].flow) then
        begin
          i:=ii shl 1-1;
          inc(edge[i].capa);inc(edge[i+1].capa);
          pop:=1;push:=2;
          q[1]:=1;
          fillchar(used,sizeof(used),false);
          fillchar(delta,sizeof(delta),0);
          delta[1]:=inf;
          used[1]:=true;
          cur:=1;
          while pop<push do
            begin
              cur:=q[pop];
              inc(pop);
              x:=last[cur];
              while x>0 do
                with edge[x] do
                  begin
                    if (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;
            end;
          critic[(i+1) shr 1]:=used[n];
          dec(edge[i].capa);dec(edge[i+1].capa);
        end;
    for i:=1 to m do
      if critic[i] then
        inc(num);
    writeln(num);
    for i:=1 to m do
      if critic[i] then
        writeln(i);
  close(output);
end.