比赛 20120705 评测结果 MMMMMMMMMM
题目名称 塔防游戏 最终得分 0
用户昵称 IMSL77 运行时间 0.000 s
代码语言 Pascal 内存使用 0.00 MiB
提交时间 2012-07-05 11:57:01
显示代码纯文本
program main;
type
  integer=longint;
const
  maxn=1100;
  maxm=5000000;
  INF=10000000;
var
  n,m,s,t,tot:integer;
  ver:array[1..maxn] of integer;
  en,next:array[1..maxm] of integer;
  l:array[1..maxm] of int64;
  d:array[0..maxn] of int64;
  mark:array[1..maxn] of boolean;
  ver2,current:array[1..maxn] of integer;
  en2,next2:array[1..maxm] of integer;
  Cap,Flow:array[1..maxm] of integer;
  level:array[1..maxn] of integer;
  Q:array[1..maxn] of integer;

  procedure Fopen;
  begin
    assign(input,'defence.in');
    reset(input);
    assign(output,'defence.out');
    rewrite(output);
  end;

  procedure Fclose;
  begin
    close(input);
    close(output);
  end;

  procedure SetGraph;
  var
    i:integer;
    u,v:integer;
    c:int64;
  begin
    readln(n,m,s,t);
    fillchar(ver,sizeof(ver),0);
    fillchar(next,sizeof(next),0);
    tot:=0;
    for i:=1 to m do
    begin
      readln(u,v,c);
      inc(tot);
      en[tot]:=v; next[tot]:=ver[u]; ver[u]:=tot;
      l[tot]:=c;
      inc(tot);
      en[tot]:=u; next[tot]:=ver[v]; ver[v]:=tot;
      l[tot]:=c;
    end;
  end;

  procedure Dijkstra;
  var
    i,j,k:integer;
    min:integer;
  begin
    for i:=0 to n do d[i]:=maxlongint*(maxlongint shr 3);
    d[s]:=0;
    fillchar(mark,sizeof(mark),true);
    for i:=1 to n do
    begin
      min:=0;
      for j:=1 to n do if mark[j] and (d[j]<d[min]) then min:=j;
      mark[min]:=false;
      k:=ver[min];
      while k>0 do
      begin
        j:=en[k];
        if mark[j] and (d[min]+l[k]<d[j]) then
          d[j]:=d[min]+l[k];
        k:=next[k];
      end;
    end;
  end;

  procedure addedge(u,v,c:integer);
  begin
    inc(tot);
    en2[tot]:=v; next2[tot]:=ver2[u]; ver2[u]:=tot;
    Cap[tot]:=c;
  end;

  procedure NewGraph;
  var
    k,u,v:integer;
  begin
    fillchar(ver2,sizeof(ver2),0);
    fillchar(next2,sizeof(next2),0);
    tot:=1;
    for u:=1 to n do
    begin
      k:=ver[u];
      while k>0 do
      begin
        v:=en[k];
        if d[u]+l[k]=d[v] then
        begin
          addedge(u,v,1);
          addedge(v,u,0);
        end;
        k:=next[k];
      end;
    end;
  end;

  function BFS:boolean;
  var
    head,tail:integer;
    k,x,y:integer;
  begin
    fillchar(level,sizeof(level),0);
    level[s]:=1;
    head:=1; tail:=2;
    Q[1]:=s;
    repeat
      x:=Q[head];
      k:=ver2[x];
      while k>0 do
      begin
        y:=en2[k];
        if (Cap[k]>Flow[k]) and (level[y]=0) then
        begin
          level[y]:=level[x]+1;
          if y=t then exit(true);
          Q[tail]:=y;
          inc(tail);
        end;
        k:=next2[k];
      end;
      inc(head);
    until head=tail;
    exit(level[t]>0);
  end;

  function min(a,b:integer):integer;
  begin
    if a<b then exit(a) else exit(b);
  end;

  function DFS(u,cur:integer):integer;
  var
    f,delta:integer;
    k,v:integer;
  begin
    if u=t then exit(cur);
    f:=cur;
    k:=current[u];
    while k>0 do
    begin
      v:=en2[k];
      if (Cap[k]>Flow[k]) and (level[u]+1=level[v]) then
      begin
        delta:=DFS(v,min(f,Cap[k]-Flow[k]));
        inc(Flow[k],delta);
        dec(Flow[k xor 1],delta);
        dec(f,delta);
        if f=0 then break;
      end;
      k:=next2[k];
    end;
    current[u]:=k;
    exit(cur-f);
  end;

  procedure Dinic;
  var
    maxflow,delta:integer;
  begin
    fillchar(Flow,sizeof(Flow),0);
    maxflow:=0;
    while BFS do
      repeat
        current:=ver2;
        delta:=DFS(s,INF);
        inc(maxflow,delta);
      until delta=0;
    writeln(maxflow);
  end;

begin
  Fopen;
  SetGraph;
  Dijkstra;
  NewGraph;
  Dinic;
  Fclose;
end.