CodeForces-1217D (위상 정렬 / DFS 판정 링)

문제의 의미

https://vjudge.net/problem/CodeForces-1217D

반지의 그 어느 것도 하나의 색상입니다, 그래서 당신은 사용되는 색상의 수를 최소화해야하는 방향 그래프 색상을주십시오.

사고

그것은 유향 그래프이기 때문에, 각 링 두 가지 색상이 만날 수 있습니다. 따라서, (2)의 최대, 최소 1.

1 DFS를 법 :

방향성 비순환 그래프 분석 DFS를 사용하여, 컬러 엣지 2의 마지막 조각을 구성하는 각 링은, (A)는 남은 염색.

2 위상 정렬 방법

점의 수는 다음 링 단조하지, 마지막 포인트는 시작 지점으로 다시 연결됩니다 때문에 경우 쉽게, 유향 그래프, 찾을 수 있습니다.

우리가 유를 넣어 그래서, 다음 출력 염색 프로토콜이있는 경우 V는, 링, 2를 염색 한 후 위상 정렬이 선고 링 그렇지 않으면 최대 출력 1 <V는 1, u는 염색>.

코드

방법 1 :

#INCLUDE <비트 / stdc ++ H.> 
네임 스페이스를 사용하여 표준; 
#DEFINE INF 0x3f3f3f3f 
#DEFINE LL 긴 긴 
CONST INT N = 5e3 + (5); 
CONST INT 개조 1E9 + = 7; 
CONST 두 EPS = 1E-8; 
CONST 이중 PI = ACOS (-1.0); 
#DEFINE lowbit (X) (X는 (- X)) 
벡터 <INT> g [N]; 
[N]과 E INT [N] [N], 힘 [N], COL [N], GG; 
보이드 DFS (INT U) 
{ 
    INT SZ = g [U] 크기는 (); 
    에서 [U]는 1 =; 
    대해 INT (I = 0; I <SZ; I ++) 
    { 
        INT V = g [U] [I]; 
        경우 (힘이 [V]!) 
        { 
            힘이 [V] = 1; 
            COL [E [U] [V] = 1; 
            DFS (V); 
        } 
        다른 ([V]에 있으면) 
        {
            COL [E [U] [V] = 2; 
            GG = 1; 
        } 
        다른 
        { 
            COL [E [U] [V] = 1; 
        } 
    } 
    의 [U] = 0; 
} 
INT 주 () 
{ 
    표준 : IOS :: sync_with_stdio (거짓); 
    INT의 N, m; 
    반면 (CIN >> >> N m) 
    { 
        memset 함수 (힘, 0는 sizeof (힘)); 
        위한 (INT 난 = 1; I <= m; I ++) 
        { 
            INT U, V; 
            CIN >> >> U V; 
            g [U] .push_back (V); 
            E [U]는 [V] 나 =; 
        } 
        GG = 0; 
        위한 (INT 난 = 1; I <= N; I ++) 
        {  
            (! 힘 [I])의 경우
            {
             // COL [I] = 1; 
                힘 [I] = 1; 
                DFS (I); 
            } 
        } 
        (GG!의) 경우에 
        { 
            COUT << 1 << ENDL; 
            위한 (INT 난 = 1; I <= m; I ++) 
                COUT << 1 << ""; 
            COUT << ENDL; 
        } 
        다른 
        { 
            COUT << 2 << ENDL; 
            경우 (; I <= m I ++ INT 난 = 1) 
                COUT << COL [I]를 << ""; 
            COUT << ENDL; 
        } 
    } 
    0을 리턴; 
}

  

방법 2 :

#INCLUDE <비트 / stdc ++ H.> 
네임 스페이스를 사용하여 표준; 
#DEFINE INF 0x3f3f3f3f 
#DEFINE LL 긴 긴 
CONST INT N = 200,005; 
CONST INT 개조 1E9 + = 7; 
CONST 두 EPS = 1E-8; 
CONST 이중 PI = ACOS (-1.0); 
#DEFINE lowbit (X) (X는 (- X)) 
벡터 <INT> g [N]; 
INT COL [N], 뒤 [N]; 
INT의 N, m; 
부울 TOPO () 
{ 
    큐 <INT> Q; 
    위한 (INT 난 = 1; I <= N; I ++) 
        경우 (뒤 [I] == 0) q.push (I); 
    INT CNT = 0; 
    반면 (q.empty (!)) 
    { 
        INT t = q.front (); 
        대 (INT I : G [t]) 
        { 
            뒤 [I] -; 
            경우 (뒤 [I] == 0) 
                q.push (I);
        } 
        CNT ++; 
        () q.pop; 
    } 
    경우 (CNT = N!) 
        복귀 거짓; 
    true를 반환; 
} 
INT 주 () 
{ 
    표준 : IOS :: sync_with_stdio (거짓); 
    CIN >> >> N m; 
    위한 (INT 난 = 1; I <= m; I ++) 
    { 
        INT U, V; 
        CIN >> >> U V; 
        g [U] .push_back (V); 
        COL [I] = (U <V); 
        뒤 [V] ++; 
    } 
    (TOPO ()) 경우에 
    { 
        COUT << 1 << ENDL; 
        위한 (INT 난 = 1; I <= m; I ++) 
            COUT << 1 << ""; 
        COUT << ENDL;
        COUT << 2 << ENDL; 
        경우 (; I <= m I ++ INT 난 1 =) 
            COUT을 << COL [I] +1 << ""; 
        COUT << ENDL; 
    } 
    0을 반환; 
}

  

추천

출처www.cnblogs.com/mcq1999/p/11983585.html