給你一個?n
?個節點的?有向圖?,節點編號為?0
?到?n - 1
?,其中每個節點?至多?有一條出邊。
圖用一個大小為?n
?下標從?0?開始的數組?edges
?表示,節點?i
?到節點?edges[i]
?之間有一條有向邊。如果節點?i
?沒有出邊,那么?edges[i] == -1
?。
請你返回圖中的?最長?環,如果沒有任何環,請返回?-1
?。
一個環指的是起點和終點是?同一個?節點的路徑。
示例 1:
輸入:edges = [3,3,4,2,3] 輸出去:3 解釋:圖中的最長環是:2 -> 4 -> 3 -> 2 。 這個環的長度為 3 ,所以返回 3 。
示例 2:
輸入:edges = [2,-1,3,1] 輸出:-1 解釋:圖中沒有任何環。
提示:
n == edges.length
2 <= n <= 10^5
-1 <= edges[i] < n
edges[i] != i
分析:由于每個節點至多有一個出邊,因此每個節點最多在一個環上。對每個節點進行dfs,如果dfs時遇到的節點,是這次dfs中出現過的節點,可以判定這次dfs中碰到了環,并且當前碰到的節點一定在環上。從這個節點開始dfs,可以得到這個環的長度。對每個沒有遍歷到的節點都進行dfs后,保留最大環長度即可。
int getans(int *edges,int flag[],int edgesSize,int index)
{if(index==-1)return -1000000000;else if(!flag[index]){flag[index]=1;return getans(edges,flag,edgesSize,edges[index])+1;}else return 0;
}int dfs(int *edges,int flag[],int edgesSize,int index,int temp_flag[])
{//printf("index=%d\n",index);if(index==-1)return -1;else if(!flag[index]&&(!temp_flag[index])){flag[index]=temp_flag[index]=1;return dfs(edges,flag,edgesSize,edges[index],temp_flag);}else if(flag[index]&&temp_flag[index])return index;return -1;
}int longestCycle(int* edges, int edgesSize) {int cnt=0,l=0,ans=-1;int flag[edgesSize+5];memset(flag,0,sizeof(flag));for(int i=0;i<edgesSize;++i){if(!flag[i]){int temp_flag[edgesSize+4];memset(temp_flag,0,sizeof(temp_flag));cnt=dfs(edges,flag,edgesSize,i,temp_flag);if(cnt>=0){memset(temp_flag,0,sizeof(temp_flag));//printf("i=%d cnt=%d ",i,cnt);int temp=getans(edges,temp_flag,edgesSize,cnt);//printf("temp=%d ans=%d\n",temp,ans);ans=fmax(ans,temp);}}}return ans;
}