• GDKOI 2015 Day1 T2 单词统计Pascal


    我虽然没有参加GDKOI2015,但是我找了2015年的题练了一下。

    题意如下:

     

    思路:最大流,因为有多组数据,每次读入一组数据都要清零。

    a. 将每个点拆分成两个点,例如样例G→G`,再将字母一一编号,G=1,G`=2,D=3,D`=4……(公式:(x-1)*2*m+y*2{第x行,第y列}),将G与G`,D与D`等相连一条边,流量与cnt对应。

    如图,如果w=GD,S为原点,F为汇点,构图如图。

    b. 再向8个方向搜索是否有下一个字母,如有将它们之间连一条边,流量为无限。

    c. 定原点为0,原点与第一个字母连一条边,流量为无限,定汇点n*m*2+1,最后一个字母与汇点相连一条边,流量为无限。

    d. 建图完成之后,进行最大流计算。

    代码如下:

    program wordcount;
    const x1:array[1..8] of longint=(-1,-1,-1,0,1,1,1,0);
          y1:array[1..8] of longint=(-1,0,1,1,1,0,-1,-1);
    var n,m,x,y,i,j,k,ans,z,nn,t,c,l,h,h2,head,tail:longint;
    var s:ansistring;
    var mat:array[1..510,1..510] of char;
    var q:array[0..10000] of longint;
    var flow:array[0..510,0..510] of longint;
    var dis:array[0..510] of longint;
    function hh(i,j:longint):longint;//公式函数
    begin
      exit((i-1)*2*m+j*2);
    end;
    function dfs(x,xx:longint):longint;//求最小流,增广之后得到最大流
    var i,k:longint;
    begin
      if x=nn then exit(xx);
      for i:=0 to nn do
        if (flow[x,i]>0) and (dis[i]=dis[x]+1) then
        begin
          if flow[x,i]>xx then k:=dfs(i,xx) else k:=dfs(i,flow[x,i]);
          dec(flow[x,i],k);inc(flow[i,x],k);
          if k>0 then exit(k);
        end;
      exit(0);
    end;
    procedure bfs;//求dis(层)
    var i,now:longint;
    begin
      fillchar(dis,sizeof(dis),0);
      fillchar(q,sizeof(q),0);
      dis[0]:=1;head:=1;tail:=1;q[1]:=0;
      repeat
        now:=q[head];
        for i:=0 to nn do
          if (flow[now,i]>0) and (dis[i]=0) then
          begin
            dis[i]:=dis[now]+1;
            inc(tail);
            q[tail]:=i;
          end;
        inc(head);
      until head>tail;
    end;//以上为最大流计算(d步)
    begin
      read(t);
      for k:=1 to t do
      begin
        fillchar(q,sizeof(q),0);
        fillchar(flow,sizeof(flow),0);
        fillchar(dis,sizeof(dis),0);
        for i:=1 to 210 do
          for j:=1 to 210 do mat[i,j]:=chr(0);//以上为初始化
        readln(n,m);nn:=n*m*2+1;
        for i:=1 to n do
        begin
          readln(s);
          for j:=1 to m do mat[i,j]:=s[j];
        end;
        for i:=1 to n do
          for j:=1 to m do
            begin
              read(c);
              flow[hh(i,j)-1,hh(i,j)]:=c;//连边
            end;
        readln;
        readln(s);//以上为读入
        for i:=1 to n do
          for j:=1 to m do
          begin
            if mat[i,j]=s[1] then flow[0,hh(i,j)-1]:=maxlongint;//c步
            if mat[i,j]=s[length(s)] then flow[hh(i,j),nn]:=maxlongint;//c步
            h2:=pos(mat[i,j],s);
              for l:=1 to 8 do //向8个方向搜索
              begin
                if (mat[i+x1[l],j+y1[l]]=s[h2+1]) then
                  flow[hh(i,j),hh(i+x1[l],j+y1[l])-1]:=maxlongint;
                if (mat[i+x1[l],j+y1[l]]=s[h2-1]) then
                  flow[hh(i+x1[l],j+y1[l]),hh(i,j)-1]:=maxlongint;
              end;
           end;
        ans:=0;
        while 1=1 do
        begin
          bfs;
          if dis[nn]=0 then break;
          repeat
            z:=dfs(0,maxlongint);
            inc(ans,z);
          until z>0;
        end;
        writeln('Case #',k,': ',ans);//注意输出格式
      end;
    end.
    

      

    谢谢阅读!

    因为此程序没有经过官方测评,只跟正解程序对拍了一下,可能会有些错,请在评论区告诉我。

    另外,很抱歉,我不会打C++代码,请大家谅解。

  • 相关阅读:
    短信平台README.MD
    电子保单README.MD
    数据结构和算法(二)
    学习java数据结构和算法笔记(一)
    删除SVN信息
    工作中比较经常用到的命令
    Eclipse不正常关闭后,解决闪退问题
    文字接口数据捕获tcpdump
    Swagger2和springMVC整合测试
    SpringMybatis 整合JavaWeb
  • 原文地址:https://www.cnblogs.com/ligen1353055672/p/6285335.html
Copyright © 2020-2023  润新知