반응형

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

 

16500번: 문자열 판별

첫째 줄에 길이가 100이하인 문자열 S가 주어진다. 둘째 줄에는 A에 포함된 문자열의 개수 N(1 ≤ N ≤ 100)이 주어진다. 셋째 줄부터 N개의 줄에는 A에 포함된 단어가 한 줄에 하나씩 주어진다. A에

www.acmicpc.net

1.문제설명

처음 봤을 때 이게 왜 다이나믹 프로그래밍 문제일까 의문이 드는 문제입니다.

어떻게 다이나믹 프로그래밍으로 구현해야할지 고민이 필요합니다.

 

다이나믹 프로그래밍의 핵심은

주어진 문제를 여러개의 부분 문제로 나누어 풀고

그 결과를 이용해서 주어진 문제를 해결 하는 것입니다.

 

주어진 S 문자열의 0번 char부터 A 집합의 문자열들과 서로 비교하면서

A의 문자열이 S문자열의 부분과 일치하는지 확인합니다.

 

이 과정을 반복해서 S문자열의 몇번째 char 까지 만들 수 있는지

bool자료형의 dp 배열에 저장해두면서 그 이후의 부분을 만들 수 있는지 판단하면 됩니다.

 

그림을 보면 이해하기 쉬울겁니다.

백준 16500 문자열 판별 다이나믹 프로그래밍

softwarecontest와 software이 7번째 까지 일치하니까

dp[8] = true로 만들어줍니다

7이 아니라 8에 두는 건 인덱스 관리가 7에두는 것보다 다음 숫자인 8에 두는게 쉽기 때문입니다.

 

그 후 dp배열을 확인하면서 dp[i] == 1 인 지점부터 다시 A의 문자열들과 비교해줍니다

software은 다르니까 넘어가게 되고 contest가 8번부터 일치하므로 다시 dp[15] == 1로 만들어줍니다.

 

결과상 dp[S.length()] == 1 이라면 문자열 S를 만들 수 있다는 뜻입니다.

 

 


2.문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int n;
bool dp[101];
string s;
vector<string> A;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> s;
	cin >> n;
	
	for (int i = 0; i < n; i++) {
		string tmp;
		cin >> tmp;
		A.push_back(tmp);
	}

	for (int i = 0; i < s.length(); i++) {
		if (dp[i] || i==0) {
			int st = i;
			
			for (int j = 0; j < n; j++) {
				//부분문자열을 합칠 때 원래 문자열보다 더 길어지는 경우는 제외
				if (st + A[j].length() > s.length()) continue;

				bool flag = true;
				for (int k = 0; k < A[j].length(); k++) {
					if (A[j][k] != s[st + k]) {
						flag = false;
						break;
					}
				}

				if (flag) {
					dp[st + A[j].length()] = 1;
				}
			}
		}
	}

	cout << dp[s.length()];


	return 0;
}

 

백준 16500번 문자열 판별 C++

반응형
반응형

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

 

2294번: 동전 2

첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다. 가치가 같은 동전이 여러 번 주

www.acmicpc.net

#include <bits/stdc++.h>
using namespace std;

int n, k, arr[10001];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> k;

	fill(arr, arr + 10001, INT_MAX);

	for (int i = 0; i < n; i++) {
		int num;
		cin >> num;

		for (int j = 1; j <= k; j++) {
			if (j % num == 0) 
				arr[j] = min(arr[j], j / num);
                
			if(j-num >0 && arr[j-num]!=INT_MAX) 
				arr[j] = min(arr[j], arr[j - num] + 1);

		}

	}
	if (arr[k] == INT_MAX) cout << -1;
	else cout << arr[k];

	return 0;
}

백준 2294

반응형
반응형

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

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지

www.acmicpc.net

 

1. 문제설명

주사위를 굴려서 이동시키는 과정을 잘 구현하는게 핵심인 문제다.

 

  2
4 1 3
  5
  6

문제에서 주는 이 전개도를 잘 관찰해야 한다.

 

 

백준 14499번

이렇게 주사위가 있을 때

주사위는 6칸이므로 6칸에 어떤 숫자가 저장되는지

int 배열 arr[6]에 해당 면에 있는 숫자를 저장할 수 있다.

 

항상 맨윗면은 1번, 동쪽을 보는 면은 3번 이런식으로 주사위의 면을 고정한 채로

주사위를 굴리는 행위를 할 때마다

각 면에 저장된 숫자를 서로 바꿔주면 주사위를 굴리는 행위를 구현할 수 있다.

 

    [2]
     0  
[4] [1] [3] [6]
 0   0   0   0
    [5]
     0
    [6]
     0

위 전개도를 기준으로 주사위의 배열 방이 [1]번부터 [6]까지 있고

그 안에 해당하는 값이 있으면

주사위를 굴릴 때마다 해당 값들을 바꿔주면 된다.

 

[6]번은 주사위의 아랫면에 해당하므로

동서로 굴릴 때나 남북으로 굴릴때나 변환되어야 한다.

 

 


 

2.문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int n, m, x, y, k;
int arr[21][21];
int dice[7];

void copy_ground() {
	if (arr[x][y] == 0) {
		arr[x][y] = dice[6];
	}
	else {
		dice[6] = arr[x][y];
		arr[x][y] = 0;
	}

	cout << dice[1] << '\n';
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m >> x >> y >> k;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> arr[i][j];
		}
	}

	int order;
	for (int i = 0; i < k; i++) {
		cin >> order;

		if (order == 1) {
			if (y + 1 < m) {
				y++;
				int tmp = dice[1];
				dice[1] = dice[4];
				dice[4] = dice[6];
				dice[6] = dice[3];
				dice[3] = tmp;
				copy_ground();
			}
		}
		else if (order == 2) {
			if (y - 1 >= 0) {
				y--;
				int tmp = dice[1];
				dice[1] = dice[3];
				dice[3] = dice[6];
				dice[6] = dice[4];
				dice[4] = tmp;
				copy_ground();
			}
		}
		else if (order == 3) {
			if (x - 1 >= 0) {
				x--;
				int tmp = dice[2];
				dice[2] = dice[1];
				dice[1] = dice[5];
				dice[5] = dice[6];
				dice[6] = tmp;
				copy_ground();
			}
		}
		else if (order == 4) {
			if (x + 1 < n) {
				x++;

				int tmp = dice[1];
				dice[1] = dice[2];
				dice[2] = dice[6];
				dice[6] = dice[5];
				dice[5] = tmp;
				copy_ground();
			}
		}
	}


	return 0;
}

백준 14499번

 

반응형
반응형

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

 

10971번: 외판원 순회 2

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j

www.acmicpc.net

1. 문제설명

외판원 순회 문제입니다.

시작점을 정해주지 않았기 때문에 모든 노드에서 시작할 수 있습니다.

우선순위큐를 이용해서 최단거리를 우선으로 방문해야 메모리와 시간을 아낄 수 있습니다.

 

 

시험삼아 우선순위큐만 큐로 바꿔서 돌려봤습니다.

 

메모리 63072KB, 360ms 걸린 게 일반 큐를 이용한 것이고

메모리 2500KB, 4ms가 우선순위 큐를 이용한 것입니다.

 

메모리와 시간차이가 나는 이유는

우선순위큐를 이용할 때는 최단거리를 우선으로 방문하고 그 이외에는 방문하지 않는데

큐를 이용할 때는 이미 방문했던 점이 최단거리가 아닐 수 있기 때문에

계속해서 해당 노드의 해당 상태에 대해 불필요한 계산이 이루어져서

시간과 메모리가 많이 사용됩니다.

 

 

 

2.문제풀이코드 C++

#include <bits/stdc++.h>

int ch[11][1 << 11];
int n, arr[11][11];

struct Node {
	int cur, vis, st, dist;
	bool operator<(const Node& b) const {
		return dist > b.dist;
	}
};

using namespace std;
int main() {


	priority_queue<Node> Q;

	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> arr[i][j];
		}
		Q.push({ i,1 << i,i ,0 });
	}

	int ans = INT_MAX;

	while (!Q.empty()) {
		int cur = Q.top().cur;
		int vis = Q.top().vis;
		int st = Q.top().st;
		int dist = Q.top().dist;
		Q.pop();

		ch[cur][vis] = 1;

		if (vis == (1 << n) - 1) {
			if (arr[cur][st] != 0) ans = min(ans, dist + arr[cur][st]);
		}

		for (int i = 0; i < n; i++) {
			if (arr[cur][i] > 0 && ch[cur][vis | (1 << i)] == 0) {
				Q.push({ i,vis | (1 << i),st,dist + arr[cur][i] });
			}
		}
	}
	cout << ans << '\n';


	return 0;
}

백준 10971번 외판원 순회

 

반응형
반응형

소프트웨어 마에스트로 SQL 문제

 

이번에 소프트웨어 마에스트로 코딩테스트를 보게 되었는데

특이하게도 소마 코테에는 mysql과 web 문제가 포함되어 있습니다.

SQL 언어는 MariaDB 와 PostgreSQL 중 선택해서 응시 할 수 있습니다.

 

 

물론 알고리즘 문제에 비해 비중이 적긴 하지만

그래도 이왕 같이 공부하면 언젠가 도움이 될 거라 생각해서

프로그래머스 사이트에 있는 sql 문제 모음을 풀고 정리해봤습니다.

 

 

저도 유튜브로 생활코딩 데이터베이스 수업을 들어본 것 외에는 따로 SQL을 공부해본 적은 없습니다.

SQL을 아직 전혀 모르는 분이더라도

생활코딩 데이터베이스 수업을 한번 듣고

부족한 부분은 구글링하면서 문법을 배우면서

프로그래머스 문제를 풀면 충분히 대비할 수 있을거라 생각합니다.

프로그래머스 문제는 30문제가 좀 안되는데

기본기가 있으면 날잡고 하루정도면 충분히 풀 수 있습니다.

 

 


 

생활코딩 데이터베이스

https://www.youtube.com/watch?v=h_XDmyz--0w&list=PLuHgQVnccGMCgrP_9HL3dAcvdt8qOZxjW 

생활코딩 데이터베이스 수업

 

 

 

 

프로그래머스 SQL 고득점 KIT

https://programmers.co.kr/learn/challenges?tab=sql_practice_kit 

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

프로그래머스 sql 문제

 

 


프로그래머스 SQL 문제와 답

1.SELECT

1-1. 모든 레코드 조회하기

SELECT * 
FROM ANIMAL_INS 
ORDER BY ANIMAL_ID;

 

1-2. 역순 정렬하기

SELECT NAME, DATETIME 
FROM ANIMAL_INS 
ORDER BY ANIMAL_ID DESC;

 

 

1-3. 아픈 동물 찾기

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS 
WHERE INTAKE_CONDITION in ('Sick');

 

 

1-4. 어린 동물 찾기

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS 
WHERE INTAKE_CONDITION != 'Aged' 
ORDER BY ANIMAL_ID;

 

 

1-5. 동물의 아이디와 이름

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS;

 

 

1-6. 여러 기준으로 정렬하기

SELECT ANIMAL_ID, NAME, DATETIME 
FROM ANIMAL_INS 
ORDER BY NAME, DATETIME DESC;

 

 

1-7. 상위 n개 레코드

SELECT NAME 
FROM ANIMAL_INS 
ORDER BY DATETIME 
LIMIT 1;

mysql에서 row를 n 행만 출력하려면 LIMIT n 을 해주면 됩니다.

특정 구간을 출력하려면 LIMIT x1, x2 해주면 됩니다.

 

 


2. SUM, MAX, MIN

2-1. 최댓값 구하기

SELECT MAX(DATETIME) 
FROM ANIMAL_INS;

 

2-2. 최솟값 구하기

SELECT MIN(DATETIME) 
FROM ANIMAL_INS;

 

2-3. 동물 수 구하기

SELECT COUNT(*) 
FROM ANIMAL_INS;

 

 

2-4. 중복 제거하기

SELECT COUNT(DISTINCT NAME) 
FROM ANIMAL_INS;

mysql DISTINCT 를 이용하면 집합과 같은 효과를 냅니다.

 

 

 


3. GROUP BY

 

3-1. 고양이와 개는 몇 마리 있을까

SELECT ANIMAL_TYPE, COUNT(ANIMAL_ID) 
FROM ANIMAL_INS 
GROUP BY ANIMAL_TYPE 
ORDER BY ANIMAL_TYPE;

 

 

3-2. 동명 동물 수 찾기

SELECT NAME, COUNT(ANIMAL_ID) 
FROM ANIMAL_INS 
WHERE NAME is not null 
GROUP BY NAME 
Having COUNT(NAME) > 1
ORDER BY NAME;
 
 
 

3-3. 입양 시각 구하기(1)

SELECT HOUR(DATETIME), 
COUNT(HOUR(DATETIME)) 
FROM ANIMAL_OUTS 
WHERE (HOUR(DATETIME)>=9 and HOUR(DATETIME)<20)
GROUP BY HOUR(DATETIME) 
ORDER BY HOUR(DATETIME);​
 
 
 

3-4. 입양 시각 구하기(2)

SET @hour := -1;

SELECT (@hour := @hour + 1) as HOUR,
(SELECT COUNT(*) FROM ANIMAL_OUTS 
 WHERE HOUR(DATETIME) = @hour) as COUNT
 FROM ANIMAL_OUTS
 WHERE @hour < 23​

갑자기 띠용 하는 문제입니다.

이정도 문제는 소프트웨어 마에스트로를 준비할 때는 과감히 빼버리셔도..

 

 

 


4. IS NULL

4-1. 이름이 없는 동물의 아이디

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME is null
ORDER BY ANIMAL_ID;
 
 
 

4-2. 이름이 있는 동물의 아이디

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID;

 

 

4-3. NULL 처리하기

SELECT ANIMAL_TYPE, if(NAME IS NULL,"No name", NAME) , SEX_UPON_INTAKE
FROM ANIMAL_INS;

 

 

 


5. JOIN

 

5-1. 없어진 기록 찾기

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS
LEFT JOIN ANIMAL_INS ON
ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
where (ANIMAL_INS.ANIMAL_ID IS NULL)
ORDER BY ANIMAL_OUTS.ANIMAL_ID;
 

 

5-2. 있었는데요 없었습니다

SELECT ANIMAL_INS.ANIMAL_ID, ANIMAL_INS.NAME
FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
where (ANIMAL_INS.DATETIME > ANIMAL_OUTS.DATETIME)
ORDER BY ANIMAL_INS.DATETIME;

 

 

5-3. 오랜 기간 보호한 동물(1)

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME
FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.DATETIME IS NULL
ORDER BY ANIMAL_INS.DATETIME
LIMIT 3;​
 
 
 

5-4.보호소에서 중성화한 동물

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.ANIMAL_TYPE, ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS
INNER JOIN ANIMAL_INS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.SEX_UPON_OUTCOME != ANIMAL_INS.SEX_UPON_INTAKE
ORDER BY ANIMAL_OUTS.ANIMAL_ID;
 

6. String, Date

6-1. 루시와 엘라 찾기

SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
 
 
 

6-2. 이름에 el이 들어가는 동물 찾기

SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE UPPER(NAME) like '%EL%' and ANIMAL_TYPE='Dog'
ORDER BY NAME;

 

 

6-3. 중성화 여부 파악하기

SELECT 
ANIMAL_ID, 
NAME, 
if(SEX_UPON_INTAKE LIKE 'Neutere%' or
SEX_UPON_INTAKE LIKE 'Spayed%','O','X') as '중성화'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
 

 

6-4. 오랜 기간 보호한 동물(2)

SELECT ANIMAL_OUTS.ANIMAL_ID,ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS 
INNER JOIN ANIMAL_INS
ON ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
ORDER BY (ANIMAL_OUTS.DATETIME - ANIMAL_INS.DATETIME) DESC
LIMIT 2;​
 
 
 

6-5. DATETIME에서 DATE로 형 변환

SELECT ANIMAL_ID, NAME, MID(DATETIME, 1,10) as '날짜'
FROM ANIMAL_INS
order by ANIMAL_ID;

 

 


 

 

반응형
반응형

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

 

3780번: 네트워크 연결

입력은 여러 개의 테스트케이스로 주어진다. 입력의 첫 번째 줄에는 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스에는 기업의 수를 나타내는 N(4 ≤ N ≤ 20,000)이 주어진다. 다음은 몇

www.acmicpc.net

1.문제설명

Union & Find, dis-joint set을 이용하는 문제입니다.

재귀를 잘 이용해서 거리를 잘 구해야 풀 수 있습니다.

 

 

부가적으로 제가 50%에서 계속 틀렸는데

거리를 구할 때 (i-j)%1000 이고

답을 구할 때 %1000을 해주면 안됩니다.

답은  (i-j)%1000을 모두 합한 값입니다

즉 1000을 넘어갈 수 도 있기 때문에 답에도 %1000을 해버리면 틀립니다.

 

 

 

 


 

 

2.문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;


int d[20003];
int unf[20003];


int Find(int x) {
	if (unf[x] < 0) return x;
	int idx = Find(unf[x]);

	d[x] += d[unf[x]];
	return unf[x] = idx;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	for (int T = 0; T < t; T++) {
		memset(unf, -1, sizeof(unf));
		memset(d, 0, sizeof(d));
		int n;
		cin >> n;

		char c;

		while (1) {
			cin >> c;

			if (c == 'E') {
				int k;
				cin >> k;
				Find(k);
				cout << d[k] << '\n';
			}
			else if (c == 'I') {
				int a, b;
				cin >> a >> b;
				unf[a] = b;
				d[a] = (abs(a - b) % 1000);
			}
			else if (c == 'O') {
				break;
			}
		}
	}

	return 0;
}

반응형
반응형

학교 수업을 듣다가

virtual box로 실행한 ubuntu 에서 atom을 써야할 일이 생겼습니다.

 

그런데 우분투에서 아톰을 다운로드 하려고

ubuntu software에서 아톰을 검색했는데 나오지 않았습니다.

ubuntu 20.04 버전 인데 나오지 않네요.

atom은 ubuntu software에서 다운로드 받는 것 말고도 다운 받을 수 있는 방법이 있습니다.

 

 

https://linuxize.com/post/how-to-install-atom-text-editor-on-ubuntu-20-04/

아마 우분투 최신 버전의 ubuntu software에서는

기존의 다운 받을 수 있던 어플리케이션이 없는 경우도 있는 것 같아요

 

 

 

Ctrl + alt + T 로 터미널을 실행하고

sudo snap install atom --classic

이 코드를 쳐서 다운로드 하면 atom을 다운 받을 수 있습니다.

그리고 터미널 창에 atom 을 치면 atom 이 실행됩니다.

 

 

우분투 아톰 다운로드

 

 

우분투 아톰

 

 

 

반응형
반응형

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

 

17398번: 통신망 분할

첫 번째 줄에는 통신탑의 개수인 자연수 N, 통신탑 사이의 연결의 개수인 자연수 M, 통신망 연결 분할 횟수인 자연수 Q가 공백으로 구분되어 주어진다. (1 ≤ N ≤ 100,000, 1 ≤ M ≤ 100,000, 1 ≤ Q 

www.acmicpc.net

 

1. 문제설명

노드를 이어주는 간선을 제거했을 때

컴포넌트의 수가 증가한다면 각 컴포넌트의 노드 개수를 곱해서 결괏값에 더해야합니다.

이 문제는 이 방법대로 해결하기보다 역으로 생각해야 쉽게 풀 수 있습니다.

 

 


2.접근방법[알고리즘]

 

Union & Find 알고리즘을 응용합니다.

분할의 반대는 병합입니다. 

간선을 제거할 때 나눠지는 컴포넌트 노드의 수를 곱하는 대신

병합하기전 컴포넌트의 노드의 수를 곱하고 병합하면 더 쉽게 해결할 수 있습니다.

 

 

 


3.문제풀이코드 C++

 

#include <bits/stdc++.h>
using namespace std;

int n, m, q;
vector<pair<int, int> > v(1);
bool ch[100003];
vector<int> del;
int unf[100003];

int Find(int x) {
	if(unf[x] < 0) return x;

	return unf[x] = Find(unf[x]);
}

//루트에 하위 노드의 개수를 저장합니다
void Union(int a, int b) {
	a = Find(a);
	b = Find(b);

	if (a == b) return;

	if (unf[a] <= unf[b]) {
		unf[a] += unf[b];
		unf[b] = a;
	}
	else {
		unf[b] += unf[a];
		unf[a] = b;
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	memset(unf, -1, sizeof(unf));

	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		v.push_back({ a,b });
	}

	for (int i = 0; i < q; i++) {
		int a;
		cin >> a;
		ch[a] = 1;
		del.push_back(a);
	}

	for (int i = 1; i <= m; i++) {
		if (ch[i] == 0) {
			Union(v[i].first, v[i].second);
		}
	}

	long long ans = 0;
	for (int i = del.size() - 1; i >= 0; i--) {
		int a = v[del[i]].first;
		int b = v[del[i]].second;

		if (Find(a) != Find(b)) {
			ans += (unf[Find(a)] * unf[Find(b)]);
		}
		Union(a, b);
	}

	cout << ans << '\n';


	return 0;
}

백준 17398 통신망 분할

주의할점 : 정답이 INT_MAX를 넘어갑니다.

 

 

 

반응형

+ Recent posts