試題庫問題

2021-09-25 22:31:51 字數 2041 閱讀 3910

題目描述

假設乙個試題庫中有n道試題。每道試題都標明了所屬類別。同一道題可能有多個類別屬性。現要從題庫中抽取m 道題組成試卷。並要求試卷包含指定型別的試題。試設計乙個滿足要求的組卷演算法。

對於給定的組卷要求,計算滿足要求的組卷方案。

輸入格式

第1行有2個正整數k和n (2 <=k<= 20, k<=n<= 1000)

k 表示題庫中試題型別總數,n 表示題庫中試題總數。第2 行有k 個正整數,第i 個正整數表示要選出的型別i的題數。這k個數相加就是要選出的總題數m。接下來的n行給出了題庫中每個試題的型別資訊。每行的第1 個正整數p表明該題可以屬於p類,接著的p個數是該題所屬的型別號。

輸出格式

第i 行輸出 「i:」後接型別i的題號。如果有多個滿足要求的方案,只要輸出1個方案。如果問題無解,則輸出「no solution!」。

輸入輸出樣例

輸入

3 15

3 3 4

2 1 2

1 31 3

1 31 3

3 1 2 3

2 2 3

2 1 3

1 21 2

2 1 2

2 1 3

2 1 2

1 13 1 2 3

輸出

1: 1 6 8

2: 7 9 10

3: 2 3 4 5

這道題就是乙個簡單的最大流,一般看到這道題,我們不難想到用網路流,然後考慮建圖:

因為我們要保證每道題只用一次,所以我們超級源點s到每道題的流量為 1 即可,題到知識點的流量也為 1 ,每個知識點到超級匯點t的流量為題目要求的就行,最後判斷最大流是否等於m即可。

考慮輸出解:(方法挺多的)

對於每一道題,我們判斷題到知識點的流量是否已經被流完了,就可以判斷出是否用過這道題,而且可以判斷出在哪乙個知識點用的這道題,最後我們把答案存起來,最後按照每道題輸出即可。

其實寫匈牙利更簡單。。。。

ac**:

#pragma gcc optimize(2)

#include

#define int long long

using namespace std;

const

int n=

2000010

,m=2010

;const

int inf=

0x3f3f3f3f

;int k,n,m,s,t,h[m]

;int head[m]

,nex[n]

,w[n]

,to[n]

,tot=1;

vector<

int> res[m]

;inline

void

ade(

int a,

int b,

int c)

inline

void

add(

int a,

int b,

int c)

intbfs()

}}return h[t];}

intdfs

(int x,

int f)}if

(!fl) h[x]=-

1;return fl;

}int

dinic()

signed

main()

for(

int i=

1;i<=n;i++)}

if(dinic()

!=m)

return

puts

("no solution!"),

0;for(

int i=

1;i<=n;i++)}

for(

int i=

1;i<=k;i++

)return0;

}

試題庫問題

假設乙個試題庫中有n道試題。每道試題都標明了所屬類別。同一道題可能有多個類別屬性。現要從題庫中抽取 m 道題組成試卷。並要求試卷包含 指定型別的試題。試設計乙個滿足要求的組卷演算法。對於給定的組卷要求,計算滿足要求的組卷方案。由檔案input.txt提供輸入資料。檔案第1行有2個正整數n和k 2 k...

試題庫問題

網路流24題裡面的,這題應該不算難,建圖比較簡單,就是把源點和型別連一條流量為需求題的邊,把型別和對應的題連一條流量為1的邊,把題和匯點連一條流量為1 的邊,保證每道題只用一次。然後找型別和題之間滿流的邊,表示這題在裡面。include include include include using n...

試題庫問題

匈牙利演算法 這是題目 因為是網路流24題網路流十分擅長這種求關係的題目,所以我們優先考慮寫網路流。對於網路流一類的問題,我們優先開啟畫圖軟體思考如何建模。首先我們先把這些題目與型別之間建一條邊 接著再把這些無向邊變成有向邊,然後再加上源節點s與匯節點t,再把源節點與型別相連,把題目與匯節點相連 這...