Tarjan模板 求強連通分量

2022-05-31 17:45:09 字數 3019 閱讀 4909

tarjan求強連通分量的流程在這個部落格講的很清楚,再加上我也沒理解透,這裡就不寫了。

縮點:將同乙個連通塊內的點視為同乙個點。

扔一道模板題:codevs2822愛在心中

第一問很顯然就是求點數大於一的連通塊的個數,跑一次tarjan;

第二問腦補一下發現,縮點後,若圖中有且僅有乙個點出度為0且為愛心天使,則該點為所求的特殊愛心天使;

因為當縮點之後,圖中不存在環,若有且僅有乙個愛心天使出度為0,那麼其他點一定有通向該愛心天使的路徑。

若有兩個點出度為0,那麼他們彼此不被對方所愛。

若沒有點出度為0,則圖中存在環,矛盾。

看起來似乎沒什麼問題,但是寫出來第五個點掛掉了,**查不出錯,若有人看到這篇部落格,希望在下方指出錯誤,謝謝。

1 #include2 #include3 #include4 #include5 #include6 #include7

using

namespace

std;89

struct

edge;

1213

int a[5000][5000],dfn[10000],low[10000],head[10000],i,j,n,m,x,y,tag,ans[10000

];14

int ans1=0,head2[10000],out[10000

];15

bool visited[10000],b[10000],lowb[10000

];16 edge e[10000],e2[10000

];17 stacks;

1819

void tarjan(int

k)else

30if

(b[v])

31 low[k]=min(low[k],dfn[v]);32}

33int tmp=0;34

if(dfn[k]==low[k])while(v!=k);

42if(tmp>=2)++ans1;43}

44}4546

int ne=0;47

void add(int a,int

b)50

51void add2(int a,int

b)54

55int

main()

63 tag=0

;64 memset(dfn,0,sizeof

(dfn));

65for(i=1;i<=n;i++)

68 printf("

%d\n

",ans1);

6970 ne=0;71

int n2=0;72

73for(i=1;i<=n;i++)

78 a[low[i]][++a[low[i]][0]]=i;

79for(j=head[i];j!=-1;j=e[j].next)

84//

縮點:將low值相等的點看做乙個點85}

8687

for(i=1;i<=n2;i++)

9293

int sum=0;94

for(i=1;i<=n2;i++);99}

100101

if(sum!=1||a[j][0]<=1

)105

106for(i=1;i<=a[j][0];i++)

107 ans[i]=a[j][i];

108109 sort(ans+1,ans+1+a[j][0

]);110

111for(i=1;i<=a[j][0];i++)

112 printf("

%d "

,ans[i]);

113114 printf("\n"

);115

return0;

116 }

16.11.18:換了一種寫法a了,然而還是不知道原來的**有什麼問題;

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7struct edgee1[1000010],e2[1000010];8

int head1[600000],head2[600000],dfn[600000],low[600000],belong[600000],out[600000];9

bool instack[600000

];10 stacks;

11int

dep,ne1,ne2,ans1,n,m,co;

12void add1(int a,int

b)15

void add2(int a,int

b)18

void tarjan(int

k)28

else

if(instack[v])

29 low[k]=min(low[k],dfn[v]);30}

31int

t;32

if(low[k]==dfn[k])while(t!=k);

42if(tmp>1)++ans1;43}

44}4546

intmain()

55for(i=1;i<=n;i++)

58 printf("

%d\n

",ans1);

5960

int sum=0,ang=0;61

for(i=1;i<=n;i++)67}

68}69for(i=1;i<=co;i++)74}

75if(sum==1)80

if(sum2>1

)84 printf("\n"

);85 }else

86return0;

87}88 printf("

-1\n

");return0;

89 }

tarjan求強連通分量(模板)

include include include using namespace std const int maxn 50010 int pre maxn other maxn last maxn l intn,m intdfn maxn low maxn ans maxn st maxn belo...

模板 tarjan求強連通分量

大約是今年4月學的演算法了,後來5月的時候做題還寫了乙個退化的tarjanqaq。時間複雜度 o n m 用途 有向圖縮環 1 include 2 include3 include4 include5 include6 include7 include8 include9 include10 inc...

強連通分量 tarjan求強連通分量

雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...