Graph - GitDeveloperKim/DreamEach GitHub Wiki
- Vertex : ์ ์
- Edge : ๊ฐ์
- DAG(Directed Acyclic Graph) : ์ธ์ดํด์ด ์๋ ์ ํฅ๊ทธ๋ํ
- ์ธ์ ํ๋ ฌ (Adjacent Matrix) : 2์ฐจ์ ๋ฐฐ์ด๋ก ๊ฐ๋จํ๊ฒ ํํ, ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์ฌํ๋ค
- ์ธ์ ๋ฆฌ์คํธ (Adjacent List) : List๋ฅผ ์ด์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์ ๋ค, ๊ตฌํ์ด ๋ณต์ก
- ์ธ์ ์ (Adjacency Set)
- ๊ฐ์ ์ ๋ฐฐ์ด
// list ๋ฐฐ์ด๋ก ๊ทธ๋ํ ๊ฐ์ ํํํ๊ธฐ -> ์ด๋ ํ์ชฝ์ด ๊ณ ์ ๋์ด ์์ ๋ ๋ง์ด ์ฌ์ฉ
// declare
public static ArrayList< Node > g [];
//init
g = new ArrayList[N+1];
for (int i = 0;i <= N; i++) {
g[i] = new ArrayList<>();
}
//input
for (int e = 1; e <= E; e++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
// ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ
g[a].add(new Node(b,c));
g[b].add(new Node(a,c));
}
// ์ด์ค ๋ฆฌ์คํธ๋ก ๊ทธ๋ํ ๊ฐ์ ํํํ๊ธฐ -> ๋ฉ๋ชจ๋ฆฌ ์ต์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ค
// LinkedList ๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฐจ์ ์ผ๋ก ๊ฒ์ํ์ฌ ์ฐพ์๊ฐ๊ธฐ๋๋ฌธ์ ์๊ฐ์ด๊ณผ
// ๋ฐ๋ผ์ ArrayList๋ฅผ ๋ง์ด ์ฌ์ฉ
// declare
public static ArrayList < ArrayList < Integer > > graph;
// init
graph = new ArrayList< ArrayList < Integer > >();
// input
for (int i = 0; i < N+1; i++) {
graph.add(new ArrayList());
}
// adjacent list example
for (int i = 0; i < M; i++) {
int []temp = new int[2];
temp[0] = in.nextInt(); // src
temp[1] = in.nextInt(); // dst
graph.get(temp[0]).add(temp[1]); // from src to dst
}
// ํ ์ ์ ์ ๋ถ์ด์๋ ์ธ์ ํ๋ ฌ ์ํํ ๋ ์ฐธ์กฐ
for (int[] next : g.get(cur)) { // ๊ฐ๋จํ๊ฒ ๋ํ๋ผ์์๋ค
// next ....
}
- ์ํํ์ง ์๋ ๋ฐฉํฅ๊ทธ๋ํ์์ ์ฌ์ฉ (DAG: Direct Acyclic Graph)
- ์ฌ๋ฌ๊ฐ์ง ๋ต์ด ์กด์ฌ
- ๋ชจ๋ ์์๋ฅผ ๋ฐฉ๋ฌธํ๊ธฐ ์ ์ ํ๊ฐ ๋น๋ค๋ฉด ์ฌ์ดํด์ด ์กด์ฌํ๋ค๊ณ ํ๋จ
- DFS ๋ก๋ ๊ตฌํ ๊ฐ๋ฅ
- ์์์ ๋ ฌ ๊ฐ๋ click
- ์ง์ ์ฐจ์ (indegree) : ํน์ ํ ๋ ธ๋๋ก ๋ค์ด์ค๋ ๊ฐ์ ์ ๊ฐ์
- ์ง์ถ์ฐจ์ (outdegree) : ํน์ ํ ๋ ธ๋์์ ๋๊ฐ๋ ๊ฐ์ ์ ๊ฐ์
- ์๊ฐ๋ณต์ก๋ O(V+E)
- ์ง์ ์ฐจ์๊ฐ 0์ธ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ ๋ฃ๋๋ค
- ํ๊ฐ ๋น ๋๊น์ง ๋ค์์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค
- ํ์์ ์์๋ฅผ ๊บผ๋ด ํด๋น ๋ ธ๋์์ ๋๊ฐ๋ ์ ์ ๊ทธ๋ํ์์ ์ ๊ฑฐํ๋ค
- ์๋กญ๊ฒ ์ง์ ์ฐจ์๊ฐ 0์ด๋ ๋ ธ๋๋ฅผ ํ์ ๋ฃ๋๋ค.
- ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ฐ ๋ ธ๋๊ฐ ํ์ ๋ค์ด์จ ์์๊ฐ ์์ ์ ๋ ฌ์ ์ํํ ๊ฒฐ๊ณผ์ ๊ฐ๋ค
// input
for (int i = 0; i < M; i++) {
cin >> a;
cin >> b;
++indegree[b]; // ๋๋ฒ์งธ ๋์ฐฉ์ง ๊ฐฏ์๋ฅผ ์ ์ฅํด๋๋ค
topology[a].push_back(b);
}
// init
queue q;
for (int i = 1; i <= N; i++) {
if (indegree[i] == 0) {
q.push(i);
}
}
// topology sort
while (!q.empty()) {
int temp = q.front();
q.pop();
cout << temp << " ";
for (int i = 0; i < topology[temp].size(); i++) {
if (--indegree[topology[temp][i]] == 0) {
q.push(topology[temp][i]);
}
}
}
- ๋ฐฑ์ค 2252
- ๋ฐฑ์ค 1766
- ๋ง์ฝ bfs ๋ฅผ ๋์๋๋ฐ indegree๊ฐ์ด 0์ด ์๋ ๊ฐ์ด ๋จ์์๋ค -> ์ฌ์ดํด ์๊ธด๊ฒ
for (int i=1; i<=N; i++) {
cycle += indegree[i]; // indegree๊ฐ 0์ด ์๋ ์๊ฐ ๋จ์์๋ค? -> ์์์ ๋ ฌ ๋ค ๋ชป๋๋ฆฐ๊ฒ -> ์ฌ์ดํด ์ฒดํฌ
}
- ๊น์ด ์ฐ์ ํ์ (DFS) -> O(N^2) ?ํ์ธํ์
- ๋๋น ์ฐ์ ํ์ (BFS) -> O(V+E) ?ํ์ธํ์
- bfs & dfs ์ฝ๋
- 0-1 BFS dfs vs 01bfs vs ๋ค์ต์คํธ๋ผ
- 0-1 BFS ์๊ฐ ๋ณต์ก๋ O(E+V) click
- 0-1 BFS ์ฝ๋
public static int bfs () {
int answer = 0;
dq = new ArrayDeque<>();
dq.add(new Node(1,1,input[1][1]));
visited[1][1] = true;
while (!dq.isEmpty()) {
Node cur= dq.pollFirst();
answer = cur.sum;
int nx = cur.x;
int ny = cur.y;
if (nx == M && ny == N) {
return answer;
}
for (int i = 0; i < 4; i++) {
nx = cur.x + x[i];
ny = cur.y + y[i];
if (nx < 1 || nx > M || ny < 1 || ny > N)
continue;
if (visited[ny][nx])
continue;
visited[ny][nx] = true;
if (input[ny][nx] == 1) {
dq.addLast(new Node(nx,ny,answer+input[ny][nx])); // 1์ ๋งจ ๋ค์ ๋ฃ๋๋ค
} else {
dq.addFirst(new Node(nx,ny,answer+input[ny][nx])); // 0์ ๋งจ ์์ ๋ฃ์ด ๋จผ์ ๊บผ๋ธ๋ค
}
}
}
return answer;
}
- ๋น๊ฐ์ค ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก
- ๊ฐ์ค ๊ทธ๋ํ์์ ์ต๋จ๊ฒฝ๋ก
- ํ๊ณณ์์ ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ด๋ํ๋ ๊ฐ์ฅ ๋น ๋ฅธ๊ธธ ์ฐพ๊ธฐ
- ํ ๋์์์ ๋ค๋ฅธ ๋์๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ฑฐ๋ ์ด๋ํ๋ ๊ฐ์ฅ ๊ฒฝ์ ์ ์ธ ๋ฐฉ๋ฒ ์ฐพ๊ธฐ
- ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์์ ๋ ์ ์ ์ฌ์ด์ ๊ฒฝ๋ก๋ค ์ค์ ๊ฐ์ ์ ๊ฐ์ค์น์ ํฉ์ด ์ต์์ธ ๊ฒฝ๋ก
๋๋ฌด์ํค ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
- ๋ค์ต์คํธ๋ผ ์ต์ ํ
- ํน์ง : ์์ ๊ฐ์ ์ผ๋ก ํํ, ๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ
- ์๊ณ ๋ฆฌ์ฆ ์ค๋ช
- ์ถ๋ฐ ๋ ธ๋ ์ค์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ ์ด๊ธฐํ(๋ฌดํ๋)
- ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์์ ์ต๋จ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์งง์ ๋ ธ๋ ์ ํ
- ํด๋น ๋ ธ๋๋ฅผ ๊ฑฐ์ณ ๋ค๋ฅธ ๋ ธ๋๋ก ๊ฐ๋ ๋น์ฉ์ ๊ณ์ฐํ์ฌ ์ต๋จ๊ฑฐ๋ฆฌ ํ ์ด๋ธ ๊ฐฑ์
- 3-4 ๊ณผ์ ๋ฐ๋ณต
// ๊ฐ์ค์น ๊ทธ๋ํ init
mat = new ArrayList>();
for (int i = 1 ; i <= n+1; i++) {
mat.add(new ArrayList<>());
}
// ์ ์ธ๋ถ
d = new int [n+1]; // ๊ฐ ๋
ธ๋์์ ์ต๋จ๊ฑฐ๋ฆฌ ๊ฐ์ค์น ์ ์ฅ
path = new int [300]; // ์กํ์ฅ ๊ฐ์ <= 200
pq = new PriorityQueue<>((int [] a, int [] b)-> (a[1] > b[1])? 1: -1); // ๊ฑฐ๋ฆฌ๊ฐ ์งง์ ์ ์ค๋ฆ์ฐจ์
for (int i = 0; i < m; i++) {
int src = in.nextInt();
int dst = in.nextInt();
int value = in.nextInt();
mat.get(src).add(new int[] {dst, value}); // ์๋ฐฉํฅ ๊ทธ๋ํ์
mat.get(dst).add(new int[] {src, value}); // ๋ฌธ์ ์์ "๊ทธ ์ฌ์ด๋ฅผ ์ค๊ฐ๋๋ฐ ํ์ํ ์๊ฐ"
}
// ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
public static void dijkstra (int src) {
pq.add(new int[] {src, 0}); // ํ์ฌ ์์น + ํด๋น ์์น์์ ๊ฐ์ค์น, 0 ์์ ์์
for (int i = 1; i < n+1; i++) {
d[i] = Integer.MAX_VALUE; // ๊ฐ ์๋ฐ์ ๋ง๋ค ์ด๊ธฐํ
}
d[src] = 0; // ์์์
while (!pq.isEmpty()) {
int [] node = pq.poll(); // ํ์ฌ ์์์
int cur_node = node[0];
int cur_dist = node[1];
// ์ต์ ํ 2021-03-26 ์ถ๊ฐ (๋๋๋น๋ ๋ค์ต์คํธ๋ผ ๊ฐ์ ์ฐธ์กฐ)
if (cur_dist > d[cur_node]) // ์ด๋ฏธ ๋ฐฉ๋ฌธ์ด ๋๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ
continue;
for (int i = 0; i < mat.get(cur_node).size(); i++) {
int next_node = mat.get(cur_node).get(i)[0];//ํ์ฌ๋
ธ๋์์ ๋ค์ ๋
ธ๋๋ก ์ด๋ํ ๋ cost
int cost = mat.get(cur_node).get(i)[1]; //ํ์ฌ๋
ธ๋์์ ๋ค์ ๋
ธ๋๋ก ์ด๋ํ ๋ cost
if (d[next_node] > cost + cur_dist) {
d[next_node] = cost + cur_dist; //์ต๋จ๊ฑฐ๋ฆฌ ๋ฐฐ์ด ์
๋ฐ์ดํธ
path [next_node] = cur_node; // ์ ๋ต ์ถ๋ ฅ์ ์ next_node ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ์ํ cur_node ์ธ๋ฑ์ค ์ ์ฅ, ๋์ ์์ ๊ฑฐ๊พธ๋ก ์ถ์ ํ ์ ์๋ค
pq.add(new int[] {next_node, d[next_node]}); // ๋ค์๋
ธ๋ ํ์ ๋ฃ๊ธฐ
}
}
}
}
- ๋ชจ๋ ๊ฐ์ ์ด ์์์ธ ๊ฒฝ์ฐ
- ์์ ๊ฐ์ ์ด ์๋ ๊ฒฝ์ฐ
- ์์ ๊ฐ์ ์ํ์ ์๋ ๊ฒฝ์ฐ
- ์์ ๊ฐ์ ์ํ์ด ์๋ ๊ฒฝ์ฐ
- ์์ ๊ฐ์ ์ ์ํ์ ๊ฐ์งํ ์ ์๋ค
- ๋ฒจ๋ง ํฌ๋์ ๊ธฐ๋ณธ ์๊ฐ ๋ณต์ก๋๋ O(VE)๋ก ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ๋นํด ๋๋ฆฝ๋๋ค.
- ์ถ๋ฐ ๋ ธ๋๋ฅผ ์ค์
- ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ์ ์ด๊ธฐํ
- ๋ค์ ๊ณผ์ ์ N-1๋ฒ ๋ฐ๋ณต
- ์ ์ฒด ๊ฐ์ E๊ฐ๋ฅผ ํ๋์ฉ ํ์ธํ๋ค
- ๊ฐ ๊ฐ์ ์ ๊ฑฐ์ณ ๋ค๋ฅธ ๋ ธ๋๋ก ๊ฐ๋ ๋น์ฉ์ ๊ณ์ฐํ์ฌ ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ์ ๊ฐฑ์
- ๋ง์ฝ ์์ ๊ฐ์ ์ํ์ด ๋ฐ์ํ๋์ง ์ฒดํฌํ๊ณ ์ถ๋ค๋ฉด 3๋ฒ์ ๊ณผ์ ์ ํ๋ฒ ๋ ์ํ
- ์ด๋ ์ต๋จ ๊ฑฐ๋ฆฌ ํ ์ด๋ธ์ด ๊ฐฑ์ ๋๋ค๋ฉด ์์ ๊ฐ์ ์ํ์ด ์กด์ฌ
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
- ๋งค๋ฒ ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์์ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์งง์ ๋ ธ๋๋ฅผ ์ ํ
- ์์๊ฐ์ ์ด ์์ผ๋ฉด ์ฌ์ฉ ๋ถ๊ฐ
- ๋ฒจ๋ง ํฌ๋ ์๊ณ ๋ฆฌ์ฆ
- ๋งค๋ฒ ๋ชจ๋ ๊ฐ์ ์ ์ ๋ถ ํ์ธ
- ์์ ๊ฐ์ ์ํ ํ์ง
- ๋ชจ๋ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๊น์ง์ ์ต๋จ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ๊ณ์ฐ
- ๋จ๊ณ๋ณ๋ก ๊ฑฐ์ณ๊ฐ๋ ๋ ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ํ
- ๋งค ๋จ๊ณ๋ง๋ค ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ๋ ๋ ธ๋๋ฅผ ์ฐพ๋ ๊ณผ์ ์ด ํ์์๋ค
- ํ๋ก์ด๋ ์์ ์ 2์ฐจ์ ํ ์ด๋ธ์ ์ต๋จ๊ฑฐ๋ฆฌ ์ ๋ณด๋ฅผ ์ ์ฅ (dp)
- ํ ์ด๋ธ์ ํฌ๊ธฐ๊ฐ 500์ ๋์ด๊ฐ์ง ์๋๊ฒฝ์ฐ์ ์ฌ์ฉ
- ๊ฐ ๋จ๊ณ๋ง๋ค ํน์ ํ ๋ ธ๋ K๋ฅผ ๊ฑฐ์ณ ๊ฐ๋ ๊ฒฝ์ฐ๋ฅผ ํ์ธ
- a์์ b๋ก ๊ฐ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ณด๋ค a์์ k๋ฅผ ๊ฑฐ์ณ b๋ก ๊ฐ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ ์งง์์ง ๊ฒ์ฌ
- ์ ํ์ : Dab = min(Dab, Dak+Dkb)
V = in.nextInt(); // ์ ์
E = in.nextInt(); // ๊ฐ์
g = new int[V+1][V+1]; // ๊ฒฝ๋ก
for (int i = 0; i <= V; i++) {
for (int j = 0; j <=V; j++) {
g[i][j] = INF; // ์ต๋๊ฐ์ผ๋ก ์ธํ
}
}
for (int i = 0; i < E; i++) {
int from = in.nextInt();
int to = in.nextInt();
int value = in.nextInt();
// ๊ฒฝ๋ก ์ฑ์ฐ๊ธฐ
g[from][to] = value;
}
// ๊ฑฐ์ณ ๊ฐ๋ ๋
ธ๋
for (int k = 1; k <= V; k++) {
// ์ถ๋ฐ ๋
ธ๋
for (int i = 1; i <= V; i++) {
// ๋์ฐฉ ๋
ธ๋
for (int j = 1; j <= V; j++) {
g[i][j] = Math.min(g[i][j], g[i][k]+g[k][j]); // ๊ธฐ์กด ๊ฐ๊ณผ k๋ฅผ ๊ฑฐ์ณ์ ์จ ๊ฐ ๋น๊ตํด ์ต์๊ฐ ์
๋ ฅ, ์ ํ์ ์๊ธฐ!!
}
}
}
for (int i = 1; i <= V; i++) {
answer = Math.min(g[i][i], answer); // ์ถ๋ ฅ
}
- ์ ์ฅ ํธ๋ฆฌ๋ ์ด๋ค ๊ทธ๋ํ์ ๋ถ๋ถ ๊ทธ๋ํ๋ก ๊ทธ๋ํ์ ๋ชจ๋ ๋ ธ๋์ ๊ฐ์ ์ผ๋ถ๋ฅผ ํฌํจํ์ฌ ๋ชจ๋ ๋ ธ๋๊ฐ์ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ๋๊ฒ
- ์ฐ๊ฒฐ๊ทธ๋ํ์ด๋ฉฐ ์ฌ์ดํด์ด ์๋ค
- ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ ์ ์ฅ ํธ๋ฆฌ ์ค ๊ฐ์ค์น๊ฐ ๊ฐ์ฅ ์์ ๊ฒ์ ์๋ฏธํ๋ค
- Prim -> O(n+mlogm)
- Kruskal -> O(mlogm)
- n : ๋ ธ๋ / m : ๊ฐ์
- ์ฌ์ดํด ํ๋ณ ์๊ณ ๋ฆฌ์ฆ
- ๊ฐ ๊ฐ์ ์ ํ๋์ฉ ํ์ธํจ ๋ ๋
ธ๋์ ๋ฃจํธ ๋
ธ๋๋ฅผ ํ์ธ
- ๋ฃจํธ ๋ ธ๋๊ฐ ์๋ก ๋ค๋ฅด๋ค๋ฉด ๋ ๋ ธ๋์ ๋ํ์ฌ ํฉ์งํฉ(Union) ์ฐ์ฐ์ ์ํ
- ๋ฃจํธ ๋ ธ๋๊ฐ ์๋ก ๊ฐ๋ค๋ฉด ์ฌ์ดํด์ด ๋ฐ์
- ๊ทธ๋ํ์ ํฌํจ๋์ด ์๋ ๋ชจ๋ ๊ฐ์ ์ ๋ํ์ฌ 1๋ฒ ๊ณผ์ ๋ฐ๋ณต
- ์ฐธ๊ณ ๋ก ๋ฐฉํฅ ๊ทธ๋ํ์์์ ์ฌ์ดํด ์ฌ๋ถ๋ DFS๋ฅผ ์ด์ฉํ์ฌ ํ๋ณ
- union-find
- ๋ฐฑ์ค1197 ์ต์ ์คํจ๋ ํธ๋ฆฌ ์์ค
class Node implements Comparable{
int src;
int dst;
int weight;
Node (int s, int d, int w) {
src = s;
dst = d;
weight = w;
}
@Override
public int compareTo(Node o) {
return this.weight - o.weight;// ๊ฐ์ค์น๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
}
}
Collections.sort(arr); // ๊ฐ์ค์น๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
answer = 0;
for (Node node : arr) {
// ๋ถ๋ชจ๋
ธ๋๊ฐ ๊ฐ์์ง ๋ณด๊ณ
if (find(node.src) != find(node.dst)) {
answer += node.weight;
// ๊ฐ์ง์์ผ๋ฉด ํฉ์ณ์ค๋ค
union(node.src, node.dst);
}
}
System.out.println(answer);