POJ 2553 강 연통 분량 Tarjan
이 문제 에 대한 분석:
먼저 판단 하 는 것 은 e (a - > b), e (b - > c) = > e (a - > c) 즉 전달 관계 가 존재 하 는 것 이다. 이렇게 하면 관 계 를 전달 할 수 있다.물론 벨 맨 을 통 해 접근 성 있 는 전달 이 가능 하 다.하지만 실현 효율 이 낮은 것 은 분명 하 다.그래서 우 리 는 그림 을 많은 강 한 연결 분량 으로 줄 이 고 강 한 연결 분량 간 의 관 계 를 통 해 그 중의 모든 점 간 의 관 계 를 대표 할 수 있다. 그러면 귀 찮 게 변 의 관 계 를 전달 하지 않 고 모든 점 의 정 보 를 자신의 축소 점 에 맡 길 수 있다.S1 - > S2, 즉 S1 의 모든 점 에서 S2 까지 변 이 존재 하고 S2 - > S1 은 변 이 없다 (그렇지 않 으 면 S1, S2 는 하나의 강 한 연결 에 속한다). 분명히 S1 의 모든 점 은 sink 의 조건 에 부합 되 지 않 는 다.이 문 제 는 출도 가 없 는 강 한 연결 분량 의 모든 점 을 구하 기 위해 크기 에 따라 출력 하면 된다.
이 문 제 는 정말 줄 이지 않 고 P 배열 로 모든 점 이 처 한 강 한 연결 분량 의 레이 블 을 저장 하 는 것 이 관건 이다.각 점 의 각 변 의 관 계 를 통 해 만약 에 이 점 이 아웃 사 이 드 가 있 고 아웃 사 이 드 는 이 강 한 연결 을 다른 강 한 연결 로 연결 시 키 는 것 이다. 그래 야 이 강 한 연결 이 출 도 되 고 이 강 한 연결 표 시 를 다시 옮 겨 다 니 며 해당 되 는 출 도 없 는 강 한 연결 중의 점 을 출력 하면 된다.
//#include<iostream>
#include<stdio.h>
#include<stack>
#define MAXN 5005
using namespace std;
struct Node
{
int v;
Node *next;
}Edge[MAXN*MAXN],*ptr[MAXN];
int V,E;
int DFN[MAXN],LOW[MAXN],SCC[MAXN],P[MAXN];
bool visited[MAXN],inS[MAXN];
int SCCNum;
stack<int>myStack;
int min( int a,int b ){ return a<b?a:b; }
void addEdge( int u,int v,int num )
{
Node *p=&Edge[num];
p->v=v;
p->next=ptr[u];
ptr[u]=p;
}
int cnt;
void Tarjan(int pre)
{
LOW[pre]=DFN[pre]=++cnt;
Node *p=ptr[pre];
myStack.push(pre);
visited[pre]=true;
inS[pre]=true;
int u=pre;
while( p )
{
if( !visited[p->v] )
{
Tarjan(p->v);
LOW[u]=min( LOW[u],LOW[p->v] );
}
else if( inS[p->v] )
LOW[u]=min( LOW[u],DFN[p->v] );
p=p->next;
}
if( DFN[u]==LOW[u] )
{
int v;
SCCNum++;
do {
v=myStack.top();
myStack.pop();
inS[v]=false;
SCC[SCCNum]++;
P[v]=SCCNum;
}while( u!=v );
}
}
bool FINISH;
bool DFS( int pre )
{
visited[pre]=true;
int sum=0,i;
for( i=1;i<=SCCNum;i++ )
sum+=visited[i];
if( sum==SCCNum )
return FINISH=true;
Node *p=ptr[pre];
while( p )
{
if( !visited[p->v] )
DFS(p->v);
if( FINISH )
return true;
p=p->next;
}
return false;
}
int main()
{
while( scanf( "%d",&V )!=EOF )
{
if( !V )
break ;
scanf( "%d",&E );
int i,j;
int u,v;
for( i=0;i<=V;i++ )
ptr[i]=NULL;
cnt=0;SCCNum=0;FINISH=false;
while( !myStack.empty() ) myStack.pop();
for( i=1;i<=E;i++ )
{
scanf( "%d %d",&u,&v );
addEdge( u,v,i );
}
memset( DFN,0,sizeof(DFN) );
memset( LOW,0,sizeof(LOW) );
memset( visited,0,sizeof(visited) );
memset( inS,0,sizeof(inS) );
for( i=1;i<=V;i++ )
if( DFN[i]==0 )
Tarjan(i);
bool outD[MAXN];
memset( outD,0,sizeof(outD) );
for( int i=1;i<=V;i++ )
{
Node *p=ptr[i];
while( p )
{
if( P[i]!=P[p->v] )
outD[ P[i] ]=true;
p=p->next;
}
}
for( i=1;i<=V;i++ )
{
if( outD[P[i]]==false )
{
printf( "%d",i );break;
}
}
for( i++;i<=V;i++ )
{
if( outD[P[i]]==false )
printf( " %d",i );
}
printf( "
" );
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.