zoukankan      html  css  js  c++  java
  • 解题报告 poj 1087

    题意可以百度。

    话说,这是一个很 YD 的最大流模型题。不过似乎可用 floyd+匈牙利 做。

    最大流模板就不说了,主要说一下构图。(也就是这个题 YD 的地方)

    大致方向是这样的:虚拟源点和汇点,所有插座与汇点连边,方向指向汇点,流量为 1 。所有用电器和源点连边,指向用电器,流量为 1 。然后可以转换插头的再连边,流量为 +∞ (因为他给出的是转换器的种类,个数不限)。

    但是,YD 的地方是这里:有数据是用电器的插头的型号与插座都不一样,也就是图不连通。还有数据是有转换器的两个节点既不是用电器也不是插座,也就是需要为转换器另开节点。这样一来,总的节点数就是:m(用电器)+n(插座)+tot(为那种特殊的转换器新申请的节点)+2(源点和汇点)。

    还有一个更 YD 的,就是,当最大流>用电器,就是说将这些用电器全插上之后插座还有富余,这时要输出 0 而不是负数。

    代码(SueMiller):

    program ACRush;
    var n,m,mm:longint;
        i,j,k,ii,jj,kk,ss,tt,tot:longint;
        a,b,c:array[0..510]of string;
        t:array[0..510,0..510]of longint;
        q:array[0..3010]of longint;
        num:array[0..510]of longint;
        s,s1,s2:string;
        ans:longint;

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

    function bfs:boolean;
    var head,tail:longint;
        i:longint;
    begin
      fillchar(num,sizeof(num),0);
      head:=0;
      tail:=1;
      q[1]:=ss;
      num[ss]:=1;
      while head<tail do
        begin
          inc(head);
          for i:=0 to n+m+tot+1 do
            if t[q[head],i]>0 then
              if num[i]=0 then
                begin
                  num[i]:=num[q[head]]+1;
                  inc(tail);
                  q[tail]:=i;
                end;
        end;
      if num[tt]=0 then exit(false) else exit(true);
    end;

    function dfs(now,flow:longint):longint;
    var i,temp:longint;
    begin
      if now=tt then exit(flow);
      for i:=0 to n+m+tot+1 do
        if t[now,i]>0 then
          if num[i]=num[now]+1 then
            begin
              temp:=dfs(i,min(flow,t[now,i]));
              if temp>0 then
                begin
                  dec(t[now,i],temp);
                  inc(t[i,now],temp);
                  exit(temp);
                end;
            end;
      exit(0);
    end;

    begin
      readln(n);
      for i:=1 to n do
        readln(a[i]);
      readln(m);

      for i:=1 to m do
        begin
          readln(s);
          s1:=copy(s,pos(' ',s)+1,length(s)-pos(' ',s));
          for j:=1 to n do
            if a[j]=s1 then
              begin
                t[i,j+m]:=maxlongint>>2;
              end;
          b[i]:=s1;
        end;

      readln(mm);
      for i:=1 to mm do
        begin
          readln(s);
          s2:=copy(s,pos(' ',s)+1,length(s)-pos(' ',s));
          s1:=copy(s,1,pos(' ',s)-1);
          ii:=0;jj:=0;
          for j:=1 to n+m+tot do
            begin
              if (j>m) and (j<=m+n) then
                begin
                  if a[j-m]=s1 then ii:=j;
                  if a[j-m]=s2 then jj:=j;
                end;
              if j<=m then
                begin
                  if b[j]=s1 then ii:=j;
                  if b[j]=s2 then jj:=j;
                end;
              if j>m+n then
                begin
                  if c[j-m-n]=s1 then ii:=j;
                  if c[j-m-n]=s2 then jj:=j;
                end;
              if (ii>0) and (jj>0) then t[ii,jj]:=maxlongint>>2;
            end;

          if ii=0 then
            begin
              inc(tot);
              c[tot]:=s1;
            end;
          if jj=0 then
            begin
              inc(tot);
              c[tot]:=s2;
            end;
          if (ii=0) and (jj=0) then
            t[m+n+tot-1,m+n+tot]:=maxlongint>>2;
        end;

      ss:=0;tt:=m+n+tot+1;
      for i:=1 to m do
        t[ss,i]:=1;
      for i:=m+n+1 to m+n+tot do
        t[ss,i]:=1;
      for i:=m+1 to m+n do
        t[i,tt]:=1;

      ans:=0;
      while bfs do
        begin
          kk:=dfs(ss,maxlongint>>2);
          while kk>0 do
            begin
              inc(ans,kk);
              kk:=dfs(ss,maxlongint>>2);
            end;
        end;

      if ans>m then ans:=m;
      writeln(m-ans);
    end.

  • 相关阅读:
    页面置换算法
    常见内存分配算法
    进程枚举
    NET程序之小试牛刀
    周易起名大师 v18.0算法分析
    VMP分析笔记(cmp命令在VM中的表达)
    一个重启验证软件的算法分析
    一次艰辛的算法分析---------飘零4.0封包分析
    某音频格式转换器算法分析
    一次苦中作乐的追码过程(下)
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2353933.html
Copyright © 2011-2022 走看看