tarjan演算法 杭電迷宮城堡。

2021-08-01 03:08:10 字數 1677 閱讀 2468

思路:這題運用到tarjan演算法 剛看這個演算法一臉蒙b,然後通過閱讀別人的部落格算是掌握的差不多了。這個演算法中用到兩個陣列第乙個dfn,low,第乙個陣列是用來記錄深搜的順序的,第二個陣列是用來儲存i節點能夠追溯到他這個強連通分量最先深搜到的那個節點。具體的看演算法有關鍵注釋。我這裡簡單說下這個演算法推薦大家看下這個部落格,他這裡講的非常的詳細,這個**。

problem description

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間(n<=10000)和m條通道(m<=100000),每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩個房間都是相互連通的,即:對於任意的i和j,至少存在一條路徑可以從房間i到房間j,也存在一條路徑可以從房間j到房間i。

input

輸入包含多組資料,輸入的第一行有兩個數:n和m,接下來的m行每行有兩個數a和b,表示了一條通道可以從a房間來到b房間。檔案最後以兩個0結束。

output

對於輸入的每組資料,如果任意兩個房間都是相互連線的,輸出"yes",否則輸出"no"。

sample input

3 3

1 22 3

3 13 3

1 22 3

3 20 0

sample output

yes

no

**:

#include//我這裡採用鄰居表儲存圖的。第一次用的鄰接矩陣發現超記憶體了。

#include#include#define max 100001

typedef int vextype;

struct vnode;

typedef vnode lgraph[max];

/* vnode是頂點的結點結構 */

lgraph map;

int n,m;

int dfn[10001],low[100001],sign,count;

bool flag[10001];

void creat_l(lgraph g)

for(k=1;k<=m; k++)

}void out_l(lgraph g)

printf("\n");

}}int min(int x,int y)

//如果有點並且這個點沒有被訪問就深搜,回來的時候將low的值改變,因為強連通//分量肯定是有環的。

if(flag[v]==1) low[u]=min(low[u],low[v]);//當這個節點被訪問了那就是這個強連通分量撞到環了。然後將low值賦值為小的。

p=p->next;

} /* for(int v=1;v<=m;v++)

else if(flag[v]==1)low[u]=min(low[u],low[v]);

}}*/

if(dfn[u]==low[u])//回溯回去當他兩相等也就是這個沒有遇到環或者是 這個節點是強連通分量的第乙個深搜的節點就將sign計數器加1

}int main()

if(sign>1) printf("no\n");

else printf("yes\n");

}}

迷宮城堡 tarjan演算法

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩...

迷宮城堡 Tarjan

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩...

迷宮城堡 Tarjan入門

傳送門 hdu 1269 為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你...