본문 바로가기

algorithm

C++ 레퍼런스 (ECHMAScript syntax )구경과 백준 1774

https://cplusplus.com/reference/regex/

 

<regex> - C++ Reference

 

cplusplus.com

ECHMAScript syntax 

Regular operation does : pattern - matching - target sequence

But the regex syntax allows for special characters and expressions in the pattern:

 

Special pattern characters :

\d : digit

\D : not digit

\character 

 

Quantifiers 

*

?   : 0 or 1 

{int} : The preceding atom is matched exactly int times

{int,} :The preceding atom is matched int or more times.

{min,max} : The preceding atom is matched at least min times, but not more than max.

 

Groups

(subpattern)

(?:subpattern) 

 

Assertions : 

^ : start of line

$ : end of line

 

Seperator : | 

 

regex e(..)

regex_search(,..)

 

 

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

 

1774번: 우주신과의 교감

(1,1) (3,1) (2,3) (4,3) 이렇게 우주신들과 황선자씨의 좌표가 주어졌고 1번하고 4번이 연결되어 있다. 그렇다면 1번하고 2번을 잇는 통로를 만들고 3번하고 4번을 잇는 통로를 만들면 신들과 선자씨끼

www.acmicpc.net

문제를 읽고 나서 트리를 만드는 것이 목표임을 쉽게 이해했는데, 이 문제의 특이한 점은 트리가 미완성된 상태라는 것이었다. 트리(아니지만)가 몇 몇 노드 끼리는 연결되어 있지만 (노드 개수 - 1) 만큼의 간선은 없는 상태이다. 

그래서, 처음에는 이미 연결됨을 알고있는 노드들을 이용해서 프림 알고리즘을 사용하려고 생각했지만, 기존에 공부해서 친숙한 크루스칼 알고리즘으로 접근하였다.

주의할 점은 크루스칼 알고리즘을 구현할 때 간선의 길이는 보통 주어지는데 이 문제에서는 노드들의 좌표만 주어졌으므로 간선의 길이를 직접 구해야 한다.  그리고, 이미 연결된 노드들은 먼저 Union 한 뒤 시작해야 한다. 

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
int parent[1001]={-1,};
int height[1001]={0};

struct data {int x,y;};
vector<struct data> v;
double getDist(int a,int b){
    return sqrt(pow(v[a].x - v[b].x, 2) + pow(v[a].y - v[b].y, 2));
}

int Find(int u){
	if(parent[u]==-1) return u;
	return Find(parent[u]);
}
bool Union(int u,int v){
	u=Find(u);v=Find(v);
	if(u==v) return false;
	if(height[u]<height[v]) swap(u,v); 
		parent[v]=u;
	if(height[u]==height[v]) height[u]++;
	return true;
	
}
struct Edge{
	int u,v;
	double c;
	bool operator<(Edge rhs){
		return c<rhs.c;
	}
};
vector<Edge> edge;
int main() {
	int V,M;
	double ans=0; int cnt=0;
	cin>>V>>M;
	for(int i=1;i<=V;i++){
	    parent[i]=-1;
	    int x,y;cin>>x>>y;
	    v.push_back({x,y});
	}
	for(int i = 1; i<=V; i++){
		for(int j = 1; j <= V; j++){
		 if(i == j) continue;
		  double d = getDist(i-1,j-1);
		  edge.push_back({i,j,d});
		}
	}
	for(int i = 0; i < M; i++){
	    int x,y;cin>>x>>y;
	    Union(x,y);
	    cnt++;
	}
	sort(edge.begin(),edge.end());
	
	for(auto e:edge){
		int u=e.u,v=e.v; double c=e.c;
		if(Union(u,v)){
			ans+=c;
			cnt++;
		}
		if(cnt==V-1) break;
	}
	printf("%.2f",ans);
	return 0;
}

'algorithm' 카테고리의 다른 글

13335 트럭  (0) 2022.07.24
9345 디지털 비디오 디스크  (0) 2022.07.20
가르침  (0) 2022.05.31
2252  (0) 2022.05.23
1016  (0) 2022.05.21