본문 바로가기
problem-solving

boj 10159: 저울

by pikkaso 2021. 8. 26.

https://www.acmicpc.net/problem/10159

 

10159번: 저울

첫 줄에는 물건의 개수 N 이 주어지고, 둘째 줄에는 미리 측정된 물건 쌍의 개수 M이 주어진다. 단, 5 ≤ N ≤ 100 이고, 0 ≤ M ≤ 2,000이다. 다음 M개의 줄에 미리 측정된 비교 결과가 한 줄에 하나씩

www.acmicpc.net

 

진짜 오랜만에 포스트를 한다. 이제 주기적으로 문제를 풀기로 마음을 먹었다.

이 문제는 태그가 floyd이다. 근데 다르게 풀었다. floyd는 다른 사람 풀이를 참조해야 겠다...

기본적으로 이것도 n^3 이긴 한데 그냥 위상정렬 + dfs로 풀었다.

위와같이 6은 input edge가 0개이므로 ind=0으로 두었다.

각 노드와 비교가 불가능한 노드는 총 몇개인지를 구해야 하는데, 1을 예로 들자. 우선 비교할 수 있는걸 구해보자.

위 상황에서 6과 2와 3에서 1로 다다를 수 있으므로 각각 1씩 카운트를 해주어야 한다. 마찬가지로 1에서 reach 할 수 있는 노드들 카운트도 해주어야 한다. 이 모든 카운트된 값들을 N에서 빼준값이 답이 된다. 전자의 경우에는 1보다 먼저 위상정렬상 앞순위의 노드들부터 dfs 탐색하면서 카운트를 해줄 수 있다.  그것이 밑부분인 ans[p]++부분이다.

그리고 각 노드에서 reach 할 수 있는 노드들 갯수 (시작노드포함) 은 res로 계산해주면 된다.

만약 해당 노드가 ind값이 0이라면, 이 노드를 시작으로 위상정렬을 해준다. 6에서 시작하면 2, 3, 1, 9, 7를 1씩 카운트 먹여주고, 본인은 사라지면 된다.(6->2, 6->3, 6->7삭제) 그리고 완료했다는 의미로 check 표시를 해준다. (while내에 for문 순회하면서 만약 안해주면 이미 한걸 다시 할 수 있기때문이다.) 

 

#include<bits/stdc++.h>

using namespace std;


int n,m,from,to,ind[101],ans[101];
bool check[101], visited[101];
vector<int> edge[101];

int proc(int v){
  int res = 1;
  bool done = false;
  visited[v] = true;
  for(auto& p : edge[v]){
    if(!visited[p]){
      ans[p]++;
      res += proc(p);
      done = true;
    }
  }
  if(!done) return 1;
  return res;
}

int main(){

  memset(ind,0,sizeof(ind));
  memset(ans,0,sizeof(ans));
  memset(check,false,sizeof(check));
  cin>>n;
  cin>>m;
  for(int i = 0; i < m; i++){
    cin>>from>>to;
    edge[from].push_back(to);
    ind[to]++;
  }
  while(1){
    bool done = false;
    for(int v = 1; v <= n; v++){
      memset(visited,false,sizeof(visited));
      if(!ind[v] && !check[v]){
        done = true;
        ans[v] += proc(v);
        for(auto &p: edge[v]){
          ind[p]--;
        }
        check[v] = true;
      }
    }
    if(!done) break;
  }

  for(int i = 1; i <= n; i++){
    cout<<n-ans[i]<<'\n';
  }



  return 0;
}

 

 

'problem-solving' 카테고리의 다른 글

boj 23848: 등비수열의 합  (0) 2022.01.22
boj 12925: Numbers  (0) 2022.01.22
boj 16922: 로마 숫자 만들기  (0) 2021.06.03
boj 10265: MT  (0) 2021.04.11
boj 4225: 쓰레기 슈트  (0) 2021.04.11

댓글