Luogu p2683 신기 ac 코드 + Tarjan 템 플 릿
34606 단어 Tarjan
Tarjan 알고리즘
이것 은 그림 속 의 강 한 연결 분량 을 구 하 는 알고리즘 이다.강 한 연결 분량 은 이 서브 맵 의 모든 노드 가 서로 도착 할 수 있다 는 것 을 말한다.물론 Tarjan 의 효율 은 매우 높 고 시간 복잡 도 는 O (n + m) 이다.
여기 서 우 리 는 두 개의 관건 적 인 배열 을 사용 해 야 한다. 하 나 는 dfn 이 고 두부 뇌 라 고 부 르 며 모든 노드 가 dfs 에서 몇 번 째 로 검색 되 었 는 지 기록 하 는 것 이다. 또 하 나 는 low 이 고 모든 노드 의 뿌리 를 대표 하 며 바로 그의 강 한 연결 분량 의 시작 점 이다.
한 점 도 찾 아 본 적 이 없 으 면 계속 아래로 검색 하고 자신 에 게 가 는 점 dfn 을 업데이트 합 니 다.한 점 이 두 번 째 로 찾 혔 을 때, 그것 이 이미 강력 한 연결 분량 에 있다 는 것 을 증명 하기 때문에, 당신 을 찾 은 사람 을 뿌리 로 인정 해 야 합 니 다. (low 업데이트)
dfs 가 한 번 씩 검색 되 지 않 았 을 때 이 점 으로 계속 검색 하 세 요.
구체 적 인 코드 는 다음 과 같다.
#include
using namespace std;
inline int read(){
int s=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())s=(s<<3)+(s<<1)+(c^48);
return s*f;
}
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
//
int dfn[10001],low[10001],n,m,ans=0; //dfn: ( )
//low: , , ,like 。 LOW[] , , 。
int visit[10001],tot; //visit: 。tot:
vector<int>v[10001];//
stack<int>s;//
void tarjan(int x)
{
dfn[x]=low[x]=++tot; // dfn low 。
s.push(x); //
visit[x]=1;//
for(int i=0;i<v[x].size();i++)
{
if(!dfn[v[x][i]]) { // ( dfn )
tarjan(v[x][i]); //
low[x]=min(low[x],low[v[x][i]]); // low
}
else if(visit[v[x][i]]){ //
low[x]=min(low[x],dfn[v[x][i]]); // dfn low
}
}
if(low[x]==dfn[x]) //
{
int t=0;
while(s.top()!=x){
t++;
visit[s.top()]=0;s.pop();
}//
s.pop();visit[x]=0;
if(t)ans++;//
}
return;
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
v[x].push_back(y);//
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);// tarjan
printf("%d
",ans);
return 0;
}
다음은 현학 적 인 TarjanAC 코드 입 니 다.
#include
#define ______________________________ int
#define _____________________________ 10001
using namespace std;
inline ______________________________ read(){
______________________________ ___=0,_=1;char _______________________=getchar();
while(!isdigit(_______________________)){if(_______________________=='-')_=-1;_______________________=getchar();}
while(isdigit(_______________________)){___=___*10+_______________________-'0';_______________________=getchar();}
return ___*_;
}
inline void write(______________________________ __________________){
if(__________________<0){putchar('-');__________________=-__________________;}
if(__________________>9)write(__________________/10);
putchar(__________________%10+'0');
}
______________________________ ____________[_____________________________],_____________[_____________________________],n,m,________________=0;
______________________________ ______________[_____________________________],_________________________,________________________;
vector<______________________________>_____[_____________________________];
stack<______________________________>___;
void _______________(______________________________ __________________)
{
____________[__________________]=_____________[__________________]=++________________________;
___.push(__________________);
______________[__________________]=1;
for(______________________________ i=0;i<_____[__________________].size();i++)
{
if(!____________[_____[__________________][i]]) {
_______________(_____[__________________][i]);
_____________[__________________]=min(_____________[__________________],_____________[_____[__________________][i]]);
}
else if(______________[_____[__________________][i]]){
_____________[__________________]=min(_____________[__________________],____________[_____[__________________][i]]);
}
}
if(_____________[__________________]==____________[__________________])
{
______________________________ t=0;
while(___.top()!=__________________){
t++;
______________[___.top()]=0;___.pop();
}
___.pop();______________[__________________]=0;
if(t)________________++;
}
return;
}
______________________________ main()
{
n=read();m=read();
for(______________________________ i=1;i<=m;i++)
{
______________________________ __________________=read(),y=read();
_____[__________________].push_back(y);
}
for(______________________________ i=1;i<=n;i++)if(!____________[i])_______________(i);
printf("%d
",________________);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
BZOJ 1023 SHOI 2008 cactus 선인장 그림 선인장 DP제목: 선인장 한 그루를 정해서 이 선인장의 직경을 구하다 우선Tarjan 축소점 쌍, 개vector 또는 체인 테이블은 각 점이 어떤 점 쌍에 속하는지, 그리고 각 점 쌍에 어떤 점이 있는지 기록한다. 어떤 두 켤...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.