线性规划与网络流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

 

posted @ 2014-07-11 21:27  ZYF-ZYF  Views(233)  Comments(0Edit  收藏  举报