xyoj 1884 校園網路

2021-08-18 13:24:17 字數 2889 閱讀 6660

時間限制: 3 sec  

記憶體限制: 64 mb

提交: 4  

解決: 4

南陽理工學院共有m個系,分別編號1~m,其中各個系之間達成有一定的協議,如果某系有新軟體可用時,該系將允許一些其它的系複製並使用該軟體。但該允許關係是單向的,即:a系允許b系使用a的軟體時,b未必一定允許a使用b的軟體。

現在,請你寫乙個程式,根據各個系之間達成的協議情況,計算出最少需要新增多少個兩系之間的這種允許關係,才能使任何乙個系有軟體使用的時候,其它所有系也都有軟體可用。

第一行輸入乙個整數t,表示測試資料的組數(t<10) 每組測試資料的第一行是乙個整數m,表示共有m個系(2<=m<=100)。 隨後的m行,每行都有一些整數,其中的第i行表示系i允許這幾個系複製並使用系i的軟體。每行結尾都是乙個0,表示本行輸入結束。如果某個系不允許其它任何系使用該系軟體,則本行只有乙個0.

對於每組測試資料,輸出最少需要新增的這種允許關係的個數。

1

52 4 3 0

4 5 000

1 0

2
nyoj120

nyoj圖論

**

tarjan演算法詳解

【功能】

tarjan演算法的用途之一是,求乙個有向圖g=(v,e)裡極大強連通分量。強連通分量是指有向圖g裡頂點間能互相到達的子圖。而如果乙個強連通分量已經沒有被其它強通分量完全包含的話,那麼這個強連通分量就是極大強連通分量。

【演算法思想】

用dfs遍歷g中的每個頂點,通dfn[i]表示dfs時達到頂點i的時間,low[i]表示i所能直接或間接達到時間最小的頂點。(實際操作中low[i]不一定最小,但不會影響程式的最終結果)

程式開始時,order初始化為0,在dfs遍歷到v時,low[v]=dfn[v]=order++,

v入棧(這裡的棧不是dfs的遞迴時系統弄出來的棧)掃瞄一遍v所能直接達到的頂點k,如果 k沒有被訪問過那麼先dfs遍歷k,low[v]=min(low[v],low[k]);如果k在棧裡,那麼low[v]=min(low[v],dfn[k])(就是這裡使得low[v]不一定最小,但不會影響到這裡的low[v]會小於dfn[v])。掃瞄完所有的k以後,如果low[v]=dfn[v]時,棧裡v以及v以上的頂點全部出棧,且剛剛出棧的就是乙個極大強連通分量。

【大概的證明】

1. 在棧裡,當dfs遍歷到v,而且已經遍歷完v所能直接到達的頂點時,low[v]=dfn[v]時,v一定能到達棧裡v上面的頂點:

因為當dfs遍歷到v,而且已經dfs遞迴呼叫完v所能直接到達的頂點時(假設上面沒有low=dfn),這時如果發現low[v]=dfn[v],棧上面的頂點一定是剛才從頂點v遞迴呼叫時進棧的,所以v一定能夠到達那些頂點。

2 .dfs遍歷時,如果已經遍歷完v所能直接到達的頂點而low[v]=dfn[v],我們知道v一定能到達棧裡v上面的頂點,這些頂點的low一定小於 自己的dfn,不然就會出棧了,也不會小於dfn[v],不然low [v]一定小於dfn[v],所以棧裡v以其v以上的頂點組成的子圖是乙個強連通分量,如果它不是極大強連通分量的話low[v]也一定小於dfn[v](這裡不再詳細說),所以棧裡v以其v以上的頂點組成的子圖是乙個極大強連通分量。

【時間複雜度】

因為所有的點都剛好進過一次棧,所有的邊都訪問的過一次,所以時間複雜度為o(n+m)

// 強連通分量縮點

#include #include #include #include using namespace std;

const int max = 105;

int map[max][max];//用鄰接矩陣記錄圖

int low[max];//記錄的是節點所能找到的最先進入棧的節點的次序

int dfn[max];//記錄節點被搜尋的次序

int in[max];//統計縮點(由乙個強連通分量內的所有點所組成的集合稱為縮點)的入度

int out[max];//統計縮點(由乙個強連通分量內的所有點所組成的集合稱為縮點)的出度

int instack[max];//標記節點是否在棧中??????

int t[max];//作用?????

int n, order, res, ans;

stacks;

void init()//初始化陣列

int min(int x, int y)//找最小值

void tr(int u)

else if(instack[i])//否則如果相鄰節點已經在棧中 更新low[u](能找到的最先進入棧的節點的次序),取得是low[u]與dfn[i]的最小值

low[u] = min(low[u], dfn[i]);}}

if(dfn[u] == low[u])//如果該點的dfn值與low值相同,則說明該點是某強連通分量的第乙個點

//(因為乙個強聯通圖中有且僅有乙個節點的dfn值與low值相同,該點即是第乙個被搜尋到的點)

while(v != u);//將u之後的節點全部彈出棧,他們將構成乙個強連通分量(根據棧的特性,第乙個被訪問的節點一定在棧底)

}}void tarjan()//

void solve()

}int xx, yy;

xx = yy = 0;

for(int i = 1; i <= res; i++)

ans = xx > yy ? xx : yy; // 結果為縮點後的有向圖中出度為0或者入度為0中的大者

}int main()

tarjan();

solve();

if(res == 1)

printf("0\n");

else

printf("%d\n", ans);

}return 0;

}

校園網路(模擬)

校園網路 時間限制 3000 ms 記憶體限制 65535 kb 難度 5 描述 南陽理工學院共有m個系,分別編號1 m,其中各個系之間達成有一定的協議,如果某系有新軟體可用時,該系將允許一些其它的系複製並使用該軟體。但該允許關係是單向的,即 a系允許b系使用a的軟體時,b未必一定允許a使用b的軟體...

校園網路(模擬)

校園網路 時間限制 3000 ms 記憶體限制 65535 kb 難度 5 描述南陽理工學院共有m個系,分別編號1 m,其中各個系之間達成有一定的協議,如果某系有新軟體可用時,該系將允許一些其它的系複製並使用該軟體。但該允許關係是單向的,即 a系允許b系使用a的軟體時,b未必一定允許a使用b的軟體。...

NYOJ 120 校園網路

時間限制 3000 ms 記憶體限制 65535 kb 難度 5 描述 南陽理工學院共有m個系,分別編號1 m,其中各個系之間達成有一定的協議,如果某系有新軟體可用時,該系將允許一些其它的系複製並使用該軟體。但該允許關係是單向的,即 a系允許b系使用a的軟體時,b未必一定允許a使用b的軟體。現在,請...