试题库问题 2011-12-29

算法实现题8-7 试题库问题(习题 8-18)
´问题描述:
假设一个试题库中有n道试题。 每道试题都标明了所属类别。同一道题可能有多个类别
属性。现要从题库中抽取 m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个
满足要求的组卷算法。
´编程任务:
对于给定的组卷要求,计算满足要求的组卷方案。
´数据输入:
由文件input.txt提供输入数据。 文件第1行有2个正整数n和k (2 <=k<= 20, k<=n<= 1000)
k 表示题库中试题类型总数,n 表示题库中试题总数。第 2 行有 k 个正整数,第 i 个正整数
表示要选出的类型i的题数。这k个数相加就是要选出的总题数m。接下来的n行给出了题
库中每个试题的类型信息。每行的第1 个正整数p表明该题可以属于 p类,接着的 p个数是
该题所属的类型号。
´结果输出:
程序运行结束时,将组卷方案输出到文件 output.txt 中。文件第 i 行输出 “i:”后接类
型i的题号。如果有多个满足要求的方案,只要输出1 个方案。如果问题无解,则输出“No
Solution!”。
输入文件示例  输出文件示例
input.txt 

3 15
3 3 4
2 1 2
1 3
1 3
1 3
1 3
3 1 2 3
2 2 3
2 1 3
1 2
1 2
2 1 2
2 1 3
2 1 2
1 1
3 1 2 3

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

——————————————

 

  1 Program Stone;
  2 var i,n,m,flow,tot,s,t,le:longint;
  3     head,vh,dis,cur:array[0..2000]of longint;
  4     next,date,point:array[-20000..20000]of longint;
  5  procedure add(x,y,z:longint);
  6   begin
  7      inc(le);
  8      date[le]:=z;
  9      point[le]:=y;
 10      next[le]:=head[x];
 11      head[x]:=le;
 12      point[-le]:=x;
 13      next[-le]:=head[y];
 14      head[y]:=-le;
 15   end;
 16  Procedure init;
 17  var i,j,k,p:longint;
 18   begin
 19     readln(m,n);
 20     s:=0;t:=n+m+1;
 21     for i:=1 to m do
 22      begin
 23        read(j);
 24        inc(tot,j);
 25        add(s,i,j);
 26      end;
 27     for i:=1 to n do
 28      begin
 29        read(p);
 30        for j:=1 to p do
 31         begin
 32           read(k);
 33           add(k,i+m,1);
 34         end;
 35        readln;
 36        add(i+m,t,1);
 37      end;
 38   end;
 39 
 40  function min(a,b:longint):longint;
 41   begin
 42     if a<b then min:=a else min:=b;
 43   end;
 44  function aug(x,nf:longint):longint;
 45  var i,j,l,d,minh,ins:longint;
 46   begin
 47     if x=t then exit(nf);
 48     l:=nf;
 49     i:=cur[x];
 50     while i<>0 do
 51      begin
 52        if (date[i]>0)and(dis[point[i]]+1=dis[x]) then
 53            begin
 54              cur[x]:=i;
 55              d:=aug(point[i],min(l,date[i]));
 56              dec(date[i],d);
 57              inc(date[-i],d);
 58              dec(l,d);
 59              if (l=0)or(dis[s]=t+1) then exit(nf-l);
 60            end;
 61        i:=next[i];
 62      end;
 63     if l=nf then
 64       begin
 65         minh:=t+1;
 66         i:=head[x];
 67         while i<>0 do
 68          begin
 69            if (date[i]>0)and(dis[point[i]]<minh) then begin minh:=dis[point[i]];ins:=i;end;
 70            i:=next[i];
 71          end;
 72         cur[x]:=ins;
 73         dec(vh[dis[x]]);
 74         if vh[dis[x]]=0 then dis[s]:=t+1;
 75         dis[x]:=minh+1;
 76         inc(vh[dis[x]]);
 77       end;
 78     aug:=nf-l;
 79   end;
 80  procedure print;
 81  var i,j,k:longint;
 82   begin
 83     for i:=1 to m do
 84      begin
 85        j:=head[i];
 86        write(i,':');
 87        while j<>0 do
 88         begin
 89           if (j>0)and(date[j]=0) then write(point[j],' ');
 90           j:=next[j];
 91         end;
 92        writeln;
 93      end;
 94   end;
 95 Begin
 96  assign(input,'prog87.in');assign(output,'prog87.out');
 97  reset(input);rewrite(output);
 98    init;
 99    vh[0]:=t+1;
100    for i:=s to t do cur[i]:=head[i];
101    while dis[0]<t+1 do inc(flow,aug(s,maxlongint));
102    if flow<>tot then write('No Soluntion!')
103                 else print;
104  close(input);close(output);
105 end.
106 
107  

 

posted on 2016-03-02 20:37  Yesphet  阅读(202)  评论(0编辑  收藏  举报