日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu3594 强连通 tarjan

發布時間:2025/6/17 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu3594 强连通 tarjan 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意: 判斷是不是強連通圖 ,同時每一條邊必須只能在一個環里


思路:之前我的強連通用的全是雙深搜,結果題目的第二個要求很難判斷,一開始寫了三個深搜加上并查集,結果越寫越亂,其實就是在判斷一個邊是否只在一個環內搞不定,后來看了下網上的代碼,用的全是tarjan,沒辦法了,又學習了一下tarjan算法,學完后發現這個算法不錯,比雙深搜快一倍的時間吧,他的時間復雜度是O(n + m) n是點m是邊,tarjan算法的運行步驟為第二問的解決提供了條件,其中的stack,low,dfn配合的很好,我們要開一個數組記錄搜索路徑,然后當我們搜到一個點發現他被搜過同時他還在stack中的話,我們直接通過路徑數組原路返回到他,把路上所有的點的次數都加1(開個數組記錄次數),如果發現有大于1的直接就NO了,還有就是點有一個點的次數不要加1,就是查找路徑的第一個點的上一個點,也是路徑中的最后一個點(因為是環),這樣就ok了.


#include<stdio.h>
#include<string.h>
#include<stack>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
#define N_node 25000 + 1000
#define N_edge 55000 + 1000


using namespace std;


typedef struct
{
? ?int to ,next;
}STAR;


STAR E[N_edge];
int list[N_node] ,tot;
int mer[N_node];
int count[N_node];
int DFN[N_node] ,LOW[N_node];
int Index ,num ,okk;
int instack[N_node];
stack<int>st;?


void add(int a ,int b)
{
? ?E[++tot].to = b;
? ?E[tot].next = list[a];
? ?list[a] = tot;
}


int minn(int x ,int y)
{
? ?return x < y ? x : y;
}


void merge(int e ,int s)
{
? ?while(mer[s] != e)
? ?{
? ? ? count[s] ++;
? ? ? if(count[s] >= 2)
? ? ? {
? ? ? ? ?okk = 1;
? ? ? ? ?return ;
? ? ? }
? ? ? s = mer[s];
? ?}
}


void Tarjan(int s)
{
? ?if(okk) return;
? ?DFN[s] = LOW[s] = ?Index ++;
? ?st.push(s);
? ?instack[s] = 1;
? ?for(int k = list[s] ;k ;k = E[k].next)
? ?{
? ? ? int to = E[k].to;
? ? ? if(!DFN[to])
? ? ? {
? ? ? ? ?mer[to] = s;
? ? ? ? ?Tarjan(to);
? ? ? ? ?LOW[s] = minn(LOW[to] ,LOW[s]);
? ? ? }
? ? ? else if(instack[to])
? ? ? {
? ? ? ? ?LOW[s] = minn(DFN[to] ,LOW[s]);
? ? ? ? ?merge(to ,s);
? ? ? ? ?if(okk) return; ? ? ??
? ? ? }
? ?}
? ?if(LOW[s] == DFN[s])
? ?{
? ? ? num ++;
? ? ? if(num > 1) okk = 1; ??
? ? ? while(1)
? ? ? {
? ? ? ? ?int v = st.top();
? ? ? ? ?st.pop();
? ? ? ? ?instack[v] = 0;
? ? ? ? ?if(v == s) break;
? ? ? }
? ?}
? ?return ;
}
?
int main ()
{
? ?int t ,i ,n ,a ,b;
? ?scanf("%d" ,&t);
? ?while(t--)
? ?{
? ? ? scanf("%d" ,&n);
? ? ? memset(list ,0 ,sizeof(list));
? ? ? memset(instack ,0 ,sizeof(instack));
? ? ? memset(DFN ,0 ,sizeof(DFN));
? ? ? memset(LOW ,0 ,sizeof(LOW));
? ? ? memset(count ,0 ,sizeof(count));
? ? ? for(i = 0 ;i < n ;i ++)mer[i] = i;
? ? ? while(!st.empty()) st.pop();
? ? ? tot = Index = 1 ,num = 0;
? ? ? while(scanf("%d %d" ,&a ,&b) && a + b)
? ? ? {
? ? ? ? ?add(a ,b);
? ? ? }
? ? ? okk = 0;
? ? ? for(i = 0 ;i < n ;i ++)
? ? ? {
? ? ? ? ?if(okk) break;
? ? ? ? ?if(DFN[i]) continue;
? ? ? ? ?Tarjan(i);
? ? ? }
? ? ? if(okk) printf("NO\n");
? ? ? else printf("YES\n");
? ?}
? ?return 0;
}
? ? ??
? ? ? ? ?
? ? ? ? ?

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的hdu3594 强连通 tarjan的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。