tarjan算法模版
#include<iostream>
using namespace std;int DFN[105]; //記錄在做dfs時節點的搜索次序
int low[105]; //記錄節點能夠找到的最先訪問的祖先的記號
int count=1; //標記訪問次序,時間戳
int stack[105]; //壓入棧中
int top=-1;
int flag[105]; //標記節點是否已經在棧中
int number=0;
int j;
int matrix[105][105]={{0,1,1,0,0,0},{0,0,0,1,0,0},{0,0,0,1,1,0},{1,0,0,0,0,1},{0,0,0,0,0,1},{0,0,0,0,0,0}};
int length; //圖的長度
void tarjan(int u){
DFN[u]=low[u]=count++; //初始化兩個值,自己爲能找到的最先訪問的祖先
stack[++top]=u;
flag[u]=1; //標記爲已經在棧中
for(int v=0;v<length;v++){
if(matrix[u][v]){
if(!DFN[v]){ //如果點i沒有被訪問過
tarjan(v); //遞歸訪問
if(low[v]<low[u])
low[u]=low[v]; //更新能找的到祖先
}
else{ //如果訪問過了,並且該點的DFN更小,則
if(DFN[v]<low[u]&&flag[v]) //flag[v]這個判斷條件很重要,這樣可以避免已經確定在其他聯通圖的v,因爲u到v的單向邊而影響到u的low
low[u]=DFN[v]; //也就是已經確定了的聯通圖要剔除掉,剔除的辦法就是判斷其還在棧中,因爲已經確定了的連通圖的點
} //flag在下面的do while中已經設爲0了(即已經從棧中剔除了)
}
}
//往後回溯的時候,如果發現DFN和low相同的節點,就可以把這個節點之後的節點全部彈棧,構成連通圖
if(DFN[u]==low[u]){
number++; //記錄連通圖的數量
do{
j=stack[top--]; //依次取出,直到u
cout<<j<<" ";
flag[j]=0; //設置爲不在棧中
}while(j!=u);
cout<<endl;
}
}
int main(){
memset(DFN,0,sizeof(DFN)); //數據的初始化
memset(low,0,sizeof(low));
memset(flag,0,sizeof(flag));
length=6;
tarjan(0);
cout<<endl;
for(int i=0;i<6;i++){
cout<<"DFN["<<i<<"]:"<<DFN[i]<<" low["<<i<<"]:"<<low[i]<<endl;
}
return 0;
}
不是很好看,慢慢寫
然後就是下午打算做一套模擬題,至少100吧。。。
————————————————————————————————————————————————————————————————————————————