Skip to content

07 그래프 #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions 06_mst/shin/1197.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include<iostream>
#include<vector>
#include<tuple>
#include<algorithm>

using namespace std;

int v, e;
vector<tuple<int, int, int>> edges; // (가중치, 정점1, 정점2)
vector<tuple<int, int, int>> tree; // mst
int parent[10001];

int find_root(int x) {
if (parent[x] == x)
return x;
return parent[x] = find_root(parent[x]); // 경로 압축
}

void union_root(int v1, int v2) { // 서로 다른 두 집합 연결
v1 = find_root(v1);
v2 = find_root(v2);

if (v1 != v2)
parent[v2] = v1; // 두 집합 연결(union)
}

int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

cin >> v >> e;

int a, b, c;
for (int i = 0; i < e; i++) {
cin >> a >> b >> c;
edges.push_back({ c,a,b });
}
sort(edges.begin(), edges.end());

for (int i = 1; i <= v; i++) {
parent[i] = i;
}

for (int i = 0; i < e; i++) {
// 간선 뽑아내기
auto [w, v1, v2] = edges[i];

// 사이클이 존재하는지 확인
if (find_root(v1) == find_root(v2)) continue;

// 사이클이 발생하지 않으면, mst에 현재 간선을 추가
tree.push_back(edges[i]);

// Parent 관계 갱신
union_root(v1, v2);

// 만약 정점 개수 v에 대해 v-1개의 간선을 찾았다면 종료
if (tree.size() == v - 1) break;
}

int ans = 0;
for (int i = 0; i < tree.size(); i++) {
int w = get<0>(tree[i]);
ans += w;
}
cout << ans;

return 0;
}
90 changes: 90 additions & 0 deletions 06_mst/shin/16398.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import java.io.*;
import java.util.*;

public class BJ16398 {
static int n;
static int[][] map;
static StringTokenizer st;
static int[] parent;

static class Edge{
int v1, v2, w;

Edge(int v1, int v2, int w){
this.v1 = v1;
this.v2 =v2;
this.w = w;
}

// public int compareTo(Edge e) {
// }
}

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());

map = new int[n+1][n+1];
for(int i=0 ; i<n ; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0 ; j<n ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}

parent = new int[n+1];
for(int i=1 ; i<=n ; i++) {
parent[i] = i;
}

// 간선리스트 추출
List<Edge> edges = new ArrayList<>();
for(int i=0 ; i<n ; i++) {
for(int j=i+1 ; j<n ; j++) {
if(map[i][j] != 0)
edges.add(new Edge(i,j,map[i][j]));
}
}

// 오름차순 정렬
edges.sort((a,b)-> a.w - b.w);

List<Edge> tree = new ArrayList<>();

for(int i=0 ; i<edges.size(); i++) {
int v1 = edges.get(i).v1;
int v2 = edges.get(i).v2;
int w = edges.get(i).w;

if(find_root(v1) == find_root(v2))
continue;

tree.add(new Edge(v1,v2,w));
union(v1,v2);

if(tree.size() == n-1)
break;
}

long total = 0;
for(Edge e : tree) {
total += e.w;
}
System.out.println(total);

}

static int find_root(int v) {
if(parent[v] == v)
return v;
return parent[v] = find_root(parent[v]);
}

static void union(int v1, int v2) {
int root1 = find_root(v1);
int root2 = find_root(v2);
// 루트끼리 병합
if (root1 != root2)
parent[root2] = root1;
}
}
75 changes: 75 additions & 0 deletions 06_mst/shin/1647.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import java.io.*;
import java.util.*;

public class BJ1647 {

static class Edge{
int v1, v2, w;

Edge(int v1, int v2, int w){
this.v1 = v1;
this.v2 =v2;
this.w = w;
}

// public int compareTo(Edge e) {
// }
}
static int n,m;
static int[] parent;
static ArrayList<Edge> edges;

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());

edges = new ArrayList<>();
for(int i=0 ; i<m ; i++) {
st = new StringTokenizer(br.readLine());
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());

edges.add(new Edge(v1, v2, w));
}

edges.sort((a,b)->a.w - b.w);

parent = new int[n+1];
for (int i = 1; i <= n; i++) {
parent[i] = i;
}

long total = 0;
int maxW = 0;
for(int i=0 ; i<edges.size(); i++) {
Edge edge = edges.get(i);

// 사이클이 아닌경우
if(find_root(edge.v1) != find_root(edge.v2)){
total += edge.w;
union(edge.v1, edge.v2);
maxW = edge.w;
}
}

System.out.println(total - maxW);
}

static int find_root(int x) {
if(parent[x] == x) return x;
return parent[x] = find_root(parent[x]);
}

static void union(int x, int y) {
int root_x = find_root(x);
int root_y = find_root(y);

if(root_x != root_y) {
parent[root_y] = root_x; // 루트끼리의 병합
}
}
}
89 changes: 89 additions & 0 deletions 07_graph/shin/10026.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <iostream>
#include <queue>
#include <vector>

using namespace std;
int n;

char map[101][101];
bool isVisited[101][101];
bool isVisited2[101][101];
int cnt, cnt2; // cnt : 적록색약이 아닌 사람이 봤을때의 구역의 개수 ,cnt2 : // 적록색약인 사람이 봤을때의 구역의 개수
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };

// 적록색약이 아닌 사람이 봤을때의 구역 파악하기
void bfs(int x, int y) {
isVisited[x][y] = true;
queue<pair<int, int>> q;
q.push({ x,y });
char color = map[x][y];
while (!q.empty()) {
int topx = q.front().first;
int topy = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = topx + dx[i];
int ny = topy + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= n)
continue;
if (!isVisited[nx][ny] && map[nx][ny] == color) {
q.push({ nx,ny });
isVisited[nx][ny] = true;
}
}
}
}
// 적록색약인 사람이 봤을때의 구역 파악하기
void bfs2(int x, int y) {
isVisited2[x][y] = true;
queue<pair<int, int>> q;
q.push({ x,y });
char color = map[x][y];
while (!q.empty()) {
int topx = q.front().first;
int topy = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = topx + dx[i];
int ny = topy + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= n)
continue;
if (!isVisited2[nx][ny] && (map[nx][ny] == color ||
map[nx][ny] == 'R' && color == 'G' || map[nx][ny] == 'G' && color == 'R')) {
q.push({ nx,ny });
isVisited2[nx][ny] = true;
}
}
}
}

int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> map[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!isVisited[i][j]) {
bfs(i, j);
cnt++;
}
if (!isVisited2[i][j]) {
bfs2(i, j);
cnt2++;
}
}
}

cout <<cnt << " " << cnt2;

return 0;
}
Loading