試題庫問題

2021-10-25 15:22:31 字數 2226 閱讀 5905

匈牙利演算法

這是題目

因為是網路流24題網路流十分擅長這種求關係的題目,所以我們優先考慮寫網路流。

對於網路流一類的問題,我們優先開啟畫圖軟體思考如何建模。

首先我們先把這些題目與型別之間建一條邊:

接著再把這些無向邊變成有向邊,然後再加上源節點s與匯節點t,再把源節點與型別相連,把題目與匯節點相連:

這不就成了乙個標準的網路流模型嗎?

至於我是怎麼想出以上操作的……誒嘿~(試圖萌混過關.jpg)

話說這個不是標準套路嗎(小聲bb)

然後就該考慮如何設定邊的容量。

因為每道題只能被選擇一次,所以題目到t的邊的容量全部設為1。

設型別i

_ii​

需要選擇 k

ik_i

ki​ 道題,那麼經過它流到匯點 t 的流量必須正好為 k

ik_i

ki​ 。

如果多於 k

ik_i

ki​ 的話代表你多選了一題,小於 k

ik_i

ki​ 的話代表已經沒有題目可以選擇了。

所以我們正好把s到型別i

_ii​

的邊的容量設為 k

ik_i

ki​,這樣你就不可能因為多選題目導致出現奇奇怪怪的錯誤。

最後就是型別到題目的邊了。

可以看出,只要你不把這些邊的容量設成小於1的數就行了。

因為題目到匯點 t 的邊容量為1,所以無論你把型別到題目的邊的容量設到多大,在最大流演算法中跑出來的結果都是一樣的(如果大到爆int、ll的話當我沒說/jk)

建圖之前,邊一定要初始化,可見網路流的建圖方式(我還暫時沒寫,有空補上)

網路流求出的最大流就是你選擇的題目數量,如果最大流不等於你要選擇的題目總和,那麼無解。

邊不要建反了/kk(某位反覆建反邊的蒟蒻感覺/kk)

#include

using

namespace std;

const

int n =

1e3+27;

const

int m =

2.1e4+27

;const

int inf =

2e9+7;

struct edge e[m <<1]

;int p[n]

,eid;

void

init()

void

insert

(int u,

int v,

int c)

void

addedge

(int u,

int v,

int c)

int s,t;

int cur[n]

,dep[n]

;queue<

int> q;

bool

bfs()}

}return dep[t]!=-

1;}int

dfs(

int u,

int flow)

int res =0;

for(

int i = cur[u]

;i !=-1

;i = e[i]

.fail)}}

if(res ==0)

return res;

}int

dinic()

return res;

}int n,k,m;

intmain()

for(

int v = k +

1;v <= k + n;

++ v)

}for

(int u = k +

1;u <= n + k;

++ u)if(

dinic()

!= m)

for(

int u =

1;u <= k;

++ u)

}printf

("\n");

}return0;

}

直接最大二分圖匹配,十分無腦。

但這不屬於網路流的範圍,本蒟蒻不給予任何思路與**上的參考。

試題庫問題

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

試題庫問題

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

試題庫問題

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