# 최소 신장 트리(MST)
기본적인 최소 신장 트리에서 남자와 여자가 이어져야 한다는 점이 추가 된 문제이다.
개념 자체는 어려운 문제는 아닌 것 같은데... 많이 안 풀어 보다 보니 코드가 지저분하다....
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <list>
#include <utility>
#include <functional>
#define MAX 1005
#define INF 987654321
#define MOD 1000000009
#pragma warning(disable:4996)
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<pi, pi> ppi;
int n, m,a,b,c,ans=0;
int e[MAX][MAX],w[2][MAX];
char ch;
bool mw[MAX],visit[MAX];
vector<int> v[MAX];
int find()
// 현재 w[0][i] 값이 가장 작은 노드를 찾는다.
// 단, 이전 노드와 현재노드가 반대(남/여)여야 한다.
{
int ret = -1, mi = INF;
for (int i = 1; i <= n; i++)
{
if (visit[i]==false&&mw[i] != mw[w[1][i]] && mi > w[0][i])
ret = i, mi = w[0][i];
}
return ret;
}
int main()
{
fill_n(&e[0][0], MAX*MAX, INF);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf(" %c", &ch);
mw[i] = ch == 'M' ? true : false;
w[0][i] = INF;
}
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
if (c < e[a][b])
{
v[a].push_back(b), v[b].push_back(a);
e[a][b] = e[b][a] = c;
}
}
// 데이터 입력 받기
w[0][1] = 0, w[1][1] = 0;
mw[0] = mw[1]?false:true;
// 초기 설정 하기
int cur=find();
while (cur!=-1)
{
visit[cur] = true;
for (int i = 0; i < v[cur].size(); i++)
{
int next = v[cur][i];
if (visit[next]==false&&mw[cur] != mw[next] && w[0][next] > e[cur][next])
// 이전에 방문하지 않고, 반대(남/여) 라면 노드를 갱신해 준다.
{
w[0][next] = e[cur][next];
w[1][next] = cur;
}
}
cur = find();
}
for (int i = 1; i <= n; i++)
{
if (w[0][i] == INF)
{
printf("-1");
return 0;
}
// 갈 수 없는 대학이 있다면 -1 출력하고 종료한다.
ans += w[0][i];
}
printf("%d", ans);
return 0;
}'IT > BOJ' 카테고리의 다른 글
| 백준(BOJ) 14919 분포표 만들기 ** (0) | 2018.06.13 |
|---|---|
| 백준(BOJ) 15791 세진이의 미팅 ** (0) | 2018.06.05 |
| 백준(BOJ) 15787 기차가 어둠을 헤치고 은하수를 ** (0) | 2018.06.02 |
| 백준(BOJ) 11726 2*n 타일링 ** (0) | 2018.06.01 |
| 백준(BOJ) 11084 나이트의 염탐 ** (0) | 2018.06.01 |