zoukankan      html  css  js  c++  java
  • 线性规划与网络流4 魔术球问题

    算法实现题 8-4 魔术球问题(习题 8-14)
    问题描述:
    假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球。
    (1)每次只能在某根柱子的最上面放球。
    (2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数。
    试设计一个算法,计算出在 n 根柱子上最多能放多少个球。例如,在 4 根柱子上最多可
    放 11 个球。
    ?编程任务:
    对于给定的 n,计算在 n 根柱子上最多能放多少个球。
    ?数据输入:
    由文件 input.txt 提供输入数据。文件第 1 行有 1 个正整数 n,表示柱子数。
    ?结果输出:
    程序运行结束时,将 n 根柱子上最多能放的球数以及相应的放置方案输出到文件
    output.txt 中。文件的第一行是球数。接下来的 n 行,每行是一根柱子上的球的编号。
    输入文件示例
    输出文件示例
    input.txt

    4
    output.txt
    11
    1 8
    2 7 9
    3 6 10
    4 5 11

    注意几点:

    1.注意拆点前后数值的变化,并且是时刻注意

    2.既然已经知道他的最小路径覆盖是n,那么就不需要去找起始点,就用开标记数组以及后继数组的方式遍历即可

    代码:

      1 const inf=maxlongint;
      2 type node=record
      3      from,go,next,v:longint;
      4      end;
      5      arrtype=array[0..200000] of longint;
      6 var e:array[0..200000] of node;
      7     head,h,q,a,cur,go:arrtype;
      8     i,j,n,m,ans,maxflow,tot,l,r,s,t,x,y:longint;
      9     p,v,mark:array[0..20000] of boolean;
     10     function min(x,y:longint):longint;
     11      begin
     12      if x<y then exit(x) else exit(y);
     13      end;
     14 procedure sort(var a:arrtype;l,r:longint);
     15  var i,j,m,temp:longint;
     16  begin
     17  i:=l;j:=r;m:=a[(i+j)>>1];
     18  repeat
     19   while a[i]<m do inc(i);
     20   while a[j]>m do dec(j);
     21   if i<=j then
     22    begin
     23    temp:=a[i];a[i]:=a[j];a[j]:=temp;
     24    inc(i);dec(j);
     25    end;
     26  until i>j;
     27  if i<r then sort(a,i,r);
     28  if j>l then sort(a,l,j);
     29  end;
     30 procedure ins(x,y,z:longint);
     31  begin
     32  inc(tot);
     33  e[tot].from:=x;e[tot].go:=y;e[tot].v:=z;e[tot].next:=head[x];head[x]:=tot;
     34  end;
     35 procedure insert(x,y,z:longint);
     36  begin
     37  ins(x,y,z);ins(y,x,0);
     38  end;
     39 function bfs:boolean;
     40  var i,x,y:longint;
     41  begin
     42  fillchar(h,sizeof(h),0);
     43  l:=0;r:=1;q[1]:=s;h[s]:=1;
     44  while l<r do
     45   begin
     46   inc(l);
     47   x:=q[l];
     48   i:=head[x];
     49   while i<>0 do
     50    begin
     51    y:=e[i].go;
     52    if (e[i].v<>0) and (h[y]=0) then
     53     begin
     54      h[y]:=h[x]+1;
     55      inc(r);q[r]:=y;
     56     end;
     57    i:=e[i].next;
     58    end;
     59   end;
     60  exit (h[t]<>0);
     61  end;
     62 function dfs(x,f:longint):longint;
     63  var i,y,used,tmp:longint;
     64  begin
     65  if x=t then exit(f);
     66  used:=0;
     67  i:=cur[x];
     68  while i<>0 do
     69   begin
     70   y:=e[i].go;
     71   if (h[y]=h[x]+1) and (e[i].v<>0) then
     72    begin
     73    tmp:=dfs(y,min(e[i].v,f-used));
     74    dec(e[i].v,tmp);if e[i].v<>0 then cur[x]:=i;
     75    inc(e[i xor 1].v,tmp);
     76    inc(used,tmp);
     77    if used=f then exit(f);
     78    end;
     79   i:=e[i].next;
     80   end;
     81  if used=0 then h[x]:=-1;
     82  exit(used);
     83  end;
     84 procedure dinic;
     85  begin
     86  while bfs do
     87   begin
     88   for i:=s to t do cur[i]:=head[i];
     89   inc(maxflow,dfs(s,inf));
     90   end;
     91  end;
     92 procedure init;
     93  begin
     94  tot:=1;
     95  readln(n);m:=n;
     96  fillchar(p,sizeof(p),false);
     97  for i:=1 to 120 do p[i*i]:=true;
     98  s:=0;t:=20001;
     99  for i:=1 to n do begin insert(s,i,1);insert(i+10000,t,1);end;
    100  for i:=1 to n-1 do
    101   for j:=i+1 to n do
    102    if p[i+j] then insert(i,j+10000,1);
    103  end;
    104 procedure main;
    105  begin
    106  maxflow:=0;
    107  dinic;
    108  while true do
    109   begin
    110   inc(m);insert(s,m,1);insert(m+10000,t,1);
    111   for i:=1 to m-1 do if p[i+m] then insert(i,m+10000,1);
    112   dinic;
    113   if m-maxflow>n then break;
    114   end;
    115  writeln(m-1);
    116  //for i:=2 to tot do with e[i] do if go=0 then writeln(from,' ',go,' ',v,' ',next);
    117  for x:=1 to m-1 do
    118   begin
    119   i:=head[x];
    120   while i<>0 do
    121    begin
    122    y:=e[i].go;
    123    if e[i].v=0 then begin go[x]:=y-10000;break;end;
    124    i:=e[i].next;
    125    end;
    126   end;
    127  fillchar(mark,sizeof(mark),false);
    128  for i:=1 to m-1 do
    129   begin
    130   if mark[i] then continue;
    131   x:=i;
    132   while x<>-10000 do
    133    begin
    134    mark[x]:=true;
    135    write(x,' ');
    136    x:=go[x];
    137    end;
    138   writeln;
    139   end;
    140  end;
    141 begin
    142  assign(input,'ball.in');assign(output,'ball.out');
    143  reset(input);rewrite(output);
    144  init;
    145  main;
    146  close(input);close(output);
    147 end.
    148 
    149           
    View Code
  • 相关阅读:
    设置VSS2005使支持通过Internet访问
    Twisted网络编程必备(3)
    Python中re(正则表达式)模块学习
    Python中最快的字典排序方法
    理解Python命名机制
    Twisted网络编程必备(2)
    threading 多线程控制和处理
    Twisted网络编程必备(5)
    Python中动态创建类实例
    判断是否为字符串
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3838549.html
Copyright © 2011-2022 走看看