본문 바로가기

백준

6416 트리인가?

이건 할 수 있을 것 같은데...?

 

트리 조건이 세 개가 주어졌으니깐 세 조건 하나씩 확인하면 될 것 같다. 

 

1. 들어오는 간선이 하나도 없는 단 하나의 노드가 존재한다.

 > map 같은 걸 만들어서 들어오는 화살표 없는 노드가 하나인지 확인한다.

 

2. 루트 노드를 제외한 노드는 단 하나의 들어오는 간선이 존재한다.

 > 이것도 위의 map으로 확인하면 될 듯 

 

3. 루트에서 다른 노드로 가는 경로는 반드시 가능하며, 유일하다. 

> 경로가 두 개라면 fail.. 이까지 오면 트리 형식은 갖췄다는 거니깐 bfs 돌려서 트리 하나로 이뤄졌는지 확인하면 될 것 같다. 

 

이까지 구상은 했고 구현은 내일 해야겠다. 

 

 


 

처음 생각한 코드

 

부모 노드가 하나인지 확인하고 루트 노드가  하나인지 확인했다. 

 

부모 노드가 하나인지 확인하고 -> 이게 "루트 노드를 제외한 노드는 단 하나의 들어오는 간선이 존재한다." 조건을 확인하는 부분

 

루트 노드가  하나인지 확인했다. -> "들어오는 간선이 하나도 없는 단 하나의 노드가 존재한다."

 

이것 두 개만 확인하고 제출했더니 틀렸다ㅋㅋ

 

3. 루트에서 다른 노드로 가는 경로는 반드시 가능하며, 유일하다. 

 

이 조건을 만족하지 않은 것 같다. 

 

6 8 5 3 5 2 6 4 5 6 0 0 이 테케에서 11 10 10 11을 추가하니 트리라고 판단했다. 

 

bfs를 map으로 써야할 것 같아서 구현 안 했는데 만들어야 할 듯.. 

 

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstring>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()

using namespace std;
using i64 = long long;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;
 
int main() {
    int u, v;
    int count = 1;
    bool is_tree = true;
    
    map<int, vector<int>> child;
    map<int, vector<int>> parent;
    map<int, int> calc;
    
    while (cin >> u >> v)
    {
        if (u < 0 && v < 0)
        {
            return 0;
        }
        
        if (u == 0 && v == 0)
        {
            
            for (auto &pi : parent)
            {
                if (pi.second.size() > 1)
                {
                    is_tree = false;
                }
                    
                calc[pi.first] = 0;
            }
            
            int tmp = 0;
            for (auto &ci : calc)
            {
                if (ci.yy != 0)
                    tmp++;
            }
            
            if (tmp != 1)
                is_tree = false;
            
            if (is_tree)
                printf("Case %d is a tree.\n", count++);
            else
                printf("Case %d is not a tree.\n", count++);
            
            // 초기화
            is_tree = true;
            child.clear();
            parent.clear();
            calc.clear();
            
            continue ;
        }
        
        child[u].push_back(v);
        parent[v].push_back(u);
        calc[u] = 1;
    }
    
    
    return 0;
}

 

 

 


 

으으음 bfs 돌려서 도달하지 못하는 부분이 있다면 트리가 아니게 설정했는데 틀렸다. 

 

왜지???

 

왜지??????

 

그리고 본인이 짰지만 코드가 더러운 걸 느낀다. 으악

 

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstring>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()

using namespace std;
using i64 = long long;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;

void clear( std::queue<int> &q )
{
   std::queue<int> empty;
   std::swap( q, empty );
}

int main() {
    int u, v;
    int count = 1;
    bool is_tree = true;
    
    map<int, vector<int>> child;
    map<int, vector<int>> parent;
    map<int, int> calc;
    
    map<int, bool> visited;
    queue<int> Q;
    
    while (cin >> u >> v)
    {
        if (u < 0 && v < 0)
        {
            return 0;
        }
        
        if (u == 0 && v == 0)
        {  
            for (auto &pi : parent)
            {
                if (pi.second.size() > 1)
                {
                    is_tree = false;
                }
                    
                calc[pi.first] = 0;
            }
            
            int tmp = 0;
            int idx;
            for (auto &ci : calc)
            {
                if (ci.yy != 0)
                {
                    tmp++;
                    idx = ci.xx;
                }
            }
            
            if (tmp != 1)
            {
                is_tree = false;
            }
            
            //bfs
            Q.push(idx);
            visited[idx] = true;
            
            while (!Q.empty())
            {
                int curr = Q.front();
                Q.pop();
                
                for (int next : child[curr])
                {
                    if (!visited[next])
                    {
                        visited[next] = true;
                        Q.push(next);
                    }
                }
            }
            
            for (auto &pi : visited)
            {
                if (!pi.yy)
                    is_tree = false;
            }
            
            if (is_tree)
                printf("Case %d is a tree.\n", count++);
            else
                printf("Case %d is not a tree.\n", count++);
            
            // 초기화
            is_tree = true;
            child.clear();
            parent.clear();
            calc.clear();
            clear(Q);
            visited.clear();
            
            continue ;
        }

        visited[u] = false;
        visited[v] = false;
        child[u].push_back(v);
        parent[v].push_back(u);
        calc[u] = 1;
    }
    
    
    return 0;
}

 

아 이걸 빼먹은 듯

 

으악! 맞았다. 

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstring>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()

using namespace std;
using i64 = long long;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;

void clear( std::queue<int> &q )
{
   std::queue<int> empty;
   std::swap( q, empty );
}

int main() {
    int u, v;
    int count = 1;
    bool is_tree = true;
    
    map<int, vector<int>> child;
    map<int, vector<int>> parent;
    map<int, int> calc;
    
    map<int, bool> visited;
    queue<int> Q;
    
    while (cin >> u >> v)
    {
        if (u < 0 && v < 0)
        {
            return 0;
        }
        
        if (u == 0 && v == 0)
        {
            if (visited.size() == 0)
            {
                printf("Case %d is a tree.\n", count++);
                continue ;
            }
            
            for (auto &pi : parent)
            {
                if (pi.second.size() > 1)
                    is_tree = false;
                    
                calc[pi.first] = 0;
            }
            
            int tmp = 0;
            int idx;
            for (auto &ci : calc)
            {
                if (ci.yy != 0)
                {
                    tmp++;
                    idx = ci.xx;
                }
            }
            
            if (tmp != 1)
            {
                is_tree = false;
            }
            
            //bfs
            Q.push(idx);
            visited[idx] = true;
            
            while (!Q.empty())
            {
                int curr = Q.front();
                Q.pop();
                for (int next : child[curr])
                {
                    if (!visited[next])
                    {
                        visited[next] = true;
                        Q.push(next);
                    }
                }
            }
            
            for (auto &pi : visited)
            {
                if (!pi.yy)
                    is_tree = false;
            }
            
            if (is_tree)
                printf("Case %d is a tree.\n", count++);
            else
                printf("Case %d is not a tree.\n", count++);
            
            // 초기화
            is_tree = true;
            child.clear();
            parent.clear();
            calc.clear();
            clear(Q);
            visited.clear();
            
            continue ;
        }
        
        visited[u] = false;
        visited[v] = false;
        child[u].push_back(v);
        parent[v].push_back(u);
        calc[u] = 1;
    }
    
    
    return 0;
}

 

이번 문제는 어렵지는 않았는데 구현이 조금 힘들었다. map을 많이 써봐서 다행임

 

'백준' 카테고리의 다른 글

3018 캠프파이어  (0) 2020.08.11
2662 기업투자  (0) 2020.08.10
14437 준오는 심술쟁이!!  (0) 2020.08.07
2527 직사각형  (0) 2020.08.07
2635 수 이어가기  (0) 2020.08.06