BOJ 14907 - 프로젝트 스케줄링

image.png

흔한 유형의 위상정렬 기본문제이다.

입력만 잘 처리해주고 $d_i$를 알파벳 $i$가 끝날 수 있는 최소 시간이라고 둔다.

초기에 어떤 들어오는 간선도 없는 알파벳들은 $d_i=w_i$ 처럼 초기화 후 큐에 넣고, 그렇지 않은 알파벳들은

$d_i=Max_{j \in (j \to i)} \{d_j+w_i\}$ 처럼 계산해줄 수 있다.

void solve() {
#ifdef LOCAL
   freopen("./../in.txt", "r", stdin);
   //freopen("./../out.txt", "w", stdout);
#endif
   string raw;
   int n;
   vi cost(26, -1), in(26);
   vvi edges(26);
   while (getline(cin, raw)) {
      vs splited = split(raw);
      int to = splited[0][0] - 'A';
      cost[to] = stoi(splited[1]);

      if (sz(splited) >= 3) {
         for (char c: splited[2]) {
            edges[c - 'A'].pb(to);
            in[to]++;
         }
      }
   }
   queue<int> q;
   vi dp(26, -1);
   for (int i = 0; i < 26; i++) {
      if (cost[i] != -1 && in[i] == 0) {
         q.push(i);
         dp[i] = cost[i];
      }
   }
   while (sz(q)) {
      int cur = q.front();
      q.pop();
      for (int to: edges[cur]) {
         dp[to] = max(dp[to], dp[cur] + cost[to]);
         in[to]--;
         if (!in[to]) q.push(to);
      }
   }
   cout << maxe(dp);
}

Tags:

Categories:

Updated:

Comments