某部門在開發一個程式碼分析工具,需要分析模組之間的依賴關係,用來確定模組的初始化順序,是否有迴圈依期等問題。
“批次初始化” 是指一次可以初始化一個或多個模組。
例如 模組 1 依賴模組 2, 模組 3 也依賴模組 2, 但模組 1 和 3 沒有依賴關係, 則必須先 “批次初始化” 模組 2,再 “批次初始化” 模組 1 和 3。
現給定一組模組間的依賴關係,請計算需要 “批次初始化” 的次數。
輸入
- 第 1 行只有一個數字.表示模組總數 NNN。
- 隨後的 NNN 行依次表示模組 1 到 NNN 的依賴資料。每行的第 1 個數表示依賴的模組數量(不會超過 NNN),之後的數字表示當前模組依賴的 ID 序列。該序列不會重複出現相同的數字,模組 ID 的取值定在
[1,N]
之內。 - 模組總數 NNN 取值範圍
1<=N<=1000
- 每一行裡面的數字按
1
個空格分隔。
輸出
輸出 “批次初始化次數”
若有迴圈依賴無法完成初始化,則輸出 -1。
示例一
輸入
5
3 2 3 4
1 5
1 5
1 5
0
輸出
3
說明
- 共 5 個模組。
- 模組 1 依賴模組 2、3、4;
- 模組 2 依賴模組 5
- 模組 3 依賴模組 5
- 模組 4 依賴模組 5
- 模組 5 沒有依賴任何模組
- 批次初始化順序為
{5}->{2,3,4}->{1}
,共需 “批次初始化” 3 次
示例二
輸入
3
1 2
1 3
1 1
輸出
-1
說明
存在迴圈依賴,無法完成初始化,返回-1
解法
每次選擇出度為0的資源進行初始化,計算總共有多少躺,如果某一躺初始化的資源數為0(即找不到出度為0的資源,那麼就存在環,輸出-1返回)
#include <iostream> #include <vector> using namespace std; int main() { // 思路:每次迭代找出出度為0的資源,刪除後再次查詢出度為0的資源 int n; cin>>n; vector<pair<int, bool>> dg(n, {0, false}); // 出度,是否被載入 vector<vector<bool>> map(n, vector<bool>(n, false)); int num; for (int i = 0; i < n; i++) { cin>>dg[i].first; for (int j = 0; j < dg[i].first; j++) { cin>>num; map[i][num - 1] = true; } } int cnt = n; int times = 0; while (cnt > 0) { // 找出出度為0的資源 int del = 0; for (int i = 0; i < n; i++) { if (!dg[i].second && dg[i].first == 0) { // 將其從其他資源的出邊刪除 dg[i].second = true; for (int j = 0; j < n; j++) { if (map[j][i]) { map[j][i] = false; dg[j].first--; } } del++; cnt--; } } if (del > 0) { times++; } else if (del == 0) { cout<<-1<<endl; return 0; } } cout<<times<<endl; return 0; }