반응형
문제 출처 :
https://www.acmicpc.net/problem/6543
알고리즘 분석 :
문제 해결에 필요한 사항
1. SCC :: http://www.crocus.co.kr/950
이 문제는 진출차수(Outdegree)를 찾는 문제이다.
진출차수가 무엇을 의미하냐면
이 그림에서 1-3이 하나의 SCC이고 2가 또다른 SCC인데 2->3의 간선은 서로 다른 SCC속에 있으며 정점 2에서 정점 3으로 가는 간선이 있을 때 2의 진출 차수는 1개이고 3의 진입 차수는 1개라고 한다.
결국 답은 진출 차수가 없는 노드를 출력하면 되는것이므로 1,3이 되고 아래 그래프는 정점 1이 진출차수가 1이므로 답은 2가 된다.
그 외에 내용은 SCC를 이용하여 SCC로 묶어내고 진출 차수를 구하여 정답을 도출하면 된다.
소스 코드 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | #include <iostream> #include <cstdio> #include <algorithm> #include <stack> #include <vector> #include <memory.h> using namespace std; const int MAX = 5002; vector<int> adj[MAX]; stack<int> s; bool finish[MAX]; // SCC 분리가 완료된 정점 = true int dfsn[MAX]; // 각 노드 dfs 번호 int SCCnum[MAX]; // SCC의 인덱스 번호 int cnt; // dfs 번호 int SCCtotal; // SCC 총 개수 int dfs(int cur) { dfsn[cur] = ++cnt; s.push(cur); int result = dfsn[cur]; int len = adj[cur].size(); for (int i = 0; i < len; i++) { int next = adj[cur][i]; if (!dfsn[next]) result = min(result, dfs(next)); else if (!finish[next]) result = min(result, dfsn[next]); } if (result == dfsn[cur]) { while (1) { int t = s.top(); s.pop(); finish[t] = true; SCCnum[t] = SCCtotal; if (t == cur) break; } SCCtotal++; } return result; } int main() { while (1) { int V, E; scanf("%d", &V); if (!V) break; scanf("%d", &E); for (int i = 0; i < MAX; i++) adj[i].clear(); memset(finish, false, sizeof(finish)); memset(dfsn, 0, sizeof(dfsn)); memset(SCCnum, 0, sizeof(SCCnum)); cnt = 0; SCCtotal = 0; for (int i = 0; i < E; i++) { int from, to; scanf("%d %d", &from, &to); adj[from].push_back(to); } for (int i = 1; i <= V; i++) if (!dfsn[i]) dfs(i); int outdegree[MAX] = { 0 }; for (int i = 1; i <= V; i++) for (int j : adj[i]) if (SCCnum[i] != SCCnum[j]) outdegree[SCCnum[i]]++; vector<int> ans; for (int i = 1; i <= V; i++) if (outdegree[SCCnum[i]] == 0) printf("%d ", i); printf("\n"); } return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
반응형
'Applied > 알고리즘 문제풀이' 카테고리의 다른 글
[3977번] 축구 전술 (0) | 2017.07.22 |
---|---|
[4196번] 도미노 (0) | 2017.07.22 |
[2150번] Strongly Connected Component (0) | 2017.07.21 |
[2042번] 구간 합 구하기 (0) | 2017.07.18 |
[11050번] 이항계수 1 (0) | 2017.07.18 |