【模板】【强连通分量】【Tarjan】
2018-04-01 13:15
344 查看
题目索引:http://oi.nks.edu.cn/zh/Problem/Details/1121#include <cmath>
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define Map(A,B) Map[A][B]
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
using namespace std;
const LL Max=1e6+5;
const LL Mod=1e9+7;
const LL Inf=1e18;
stack<LL>S;
LL N,Num,Scc,Ans,In[Max],Dfn[Max],Low[Max],Bel[Max];
LL Cnt,To[Max<<1],Next[Max<<1],Head[Max];
inline LL Read(){
LL X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(LL X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
void Insert(LL X,LL Y){
To[++Cnt]=Y;Next[Cnt]=Head[X];Head[X]=Cnt;
}
void Tarjan(LL X){
LL I,J,K,Y;
Dfn[X]=Low[X]=++Num;
S.push(X);
for(I=Head[X];I;I=Next[I]){
Y=To[I];
if(!Dfn[Y]){
Tarjan(Y);
Low[X]=min(Low[X],Low[Y]);
} else if(!Bel[Y]){
Low[X]=min(Low[X],Dfn[Y]);
}
}
if(Dfn[X]==Low[X]){
++Scc;
Y=S.top();S.pop();Bel[Y]=Scc;
while(X!=Y){
Y=S.top();S.pop();Bel[Y]=Scc;
}
}
}
int main(){
LL I,J,K;
N=Read();
Fp(I,1,N,1){
Fp(J,1,N,1){
K=Read();
if(K==1){
Insert(I,J);
}
}
}
Fp(I,1,N,1){
if(!Bel[I]){
Tarjan(I);
}
}
Fp(I,1,N,1){
for(J=Head[I];J;J=Next[J]){
LL Y=To[J];
if(Bel[I]!=Bel[Y]){
In[Bel[Y]]=1;
}
}
}
Fp(I,1,Scc,1){
if(!In[I]){
Ans++;
}
}Write(Ans);
}
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define Map(A,B) Map[A][B]
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
using namespace std;
const LL Max=1e6+5;
const LL Mod=1e9+7;
const LL Inf=1e18;
stack<LL>S;
LL N,Num,Scc,Ans,In[Max],Dfn[Max],Low[Max],Bel[Max];
LL Cnt,To[Max<<1],Next[Max<<1],Head[Max];
inline LL Read(){
LL X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(LL X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
void Insert(LL X,LL Y){
To[++Cnt]=Y;Next[Cnt]=Head[X];Head[X]=Cnt;
}
void Tarjan(LL X){
LL I,J,K,Y;
Dfn[X]=Low[X]=++Num;
S.push(X);
for(I=Head[X];I;I=Next[I]){
Y=To[I];
if(!Dfn[Y]){
Tarjan(Y);
Low[X]=min(Low[X],Low[Y]);
} else if(!Bel[Y]){
Low[X]=min(Low[X],Dfn[Y]);
}
}
if(Dfn[X]==Low[X]){
++Scc;
Y=S.top();S.pop();Bel[Y]=Scc;
while(X!=Y){
Y=S.top();S.pop();Bel[Y]=Scc;
}
}
}
int main(){
LL I,J,K;
N=Read();
Fp(I,1,N,1){
Fp(J,1,N,1){
K=Read();
if(K==1){
Insert(I,J);
}
}
}
Fp(I,1,N,1){
if(!Bel[I]){
Tarjan(I);
}
}
Fp(I,1,N,1){
for(J=Head[I];J;J=Next[J]){
LL Y=To[J];
if(Bel[I]!=Bel[Y]){
In[Bel[Y]]=1;
}
}
}
Fp(I,1,Scc,1){
if(!In[I]){
Ans++;
}
}Write(Ans);
}
相关文章推荐
- 有向图强连通分量Tarjan模板
- hdu 1269 Tarjan强连通分量 模板
- hdu1269迷宫城堡(tarjan求强连通分量模板)
- tarjan 算法模板(边连通分量)
- tyvj 1111 舞会 有向图强连通分量 Kosaraju模板 tarjan模板
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(最近公共祖先)
- 二分图强连通分量 tarjan 模板
- 强连通分量Tarjan模板
- tarjan 边连通分量+2-sat 模板
- HDU 1269 迷宫城堡【Tarjan强连通分量 模板】
- 【模板】Tarjan求强连通分量
- hdu1269 Tarjan强连通分量 模板
- Tarjan模板 求割点数+桥+连通分量数 来自kuangbin
- [POJ 3180] The Cow Prom Tarjan求强连通分量 模板题
- hdu1269 Tarjan强连通分量 模板(转)
- 强连通分量Kosaraju、Tarjan【模板】
- Codeforces 427C - Checkposts 极大连通分量Tarjan算法模板题(STL实现)
- 强连通分量、Tarjan与蝴蝶结构
- sdut 3262 有向图强连通分量缩点模板