*이 글은 2022년 1월~2월 노션으로 진행한 스터디를 옮긴 글입니다.
부분 그래프
인접: 두 정점을 연결하는 간선이 존재하는 경우 인접함.
차수: 무방향 그래프는 하나의 정점에 연결된 간선의 개수, 방향 그래프는 진입차수와 진출차수
경로: 그래프에서 간선을 따라 갈 수 있는 길을 순서대로 나열함.
단순경로: 경로 중 반복되는 간선이 없는 경로
사이클: 단순경로의 시작 정점과 종료 정점이 동일한 경로
연결 그래프: 서로 다른 모든 쌍의 정점들 사이에 경로가 있는 그래프. (#완전 연결 그래프)
DAG: 사이클 갖지 않는 방향 그래프
트리도 그래프의 일종임.
구현
문제
그래프 순회/탐색
하나의 정점에서 시작해서 그래프에 있는 모든 정점을 한번씩 방문or특정 값을 탐색하는 연산.
DFS(depth first search-stack)
깊이우선탐색
스택 선호
void dfs(int v){
for(int i=0;i<path[v].size();++i){
if(!visit[path[v][i]]){
visit[path[v][i]]=1;
printf("%d ",path[v][i]);
dfs(path[v][i]);
}
}
}
BFS(breadth first search-queue)
- 너비우선탐색
- 큐 선호
```cpp
void bfs(int v){
for(int i=0;i<path[v].size();++i){
if(!visit[path[v][i]]){
q.push(path[v][i]);
visit[path[v][i]]=1;
}
}
while(!q.empty()){
int t = q.front();
q.pop();
printf("%d ",t);
bfs(t);
}
}
```
#include<bits/stdc++.h>
using namespace std;
int n,m,v;
bool visit[1005];
vector<int> path[1005];
queue<int> q;
void dfs(int v){
for(int i=0;i<path[v].size();++i){
if(!visit[path[v][i]]){
visit[path[v][i]]=1;
printf("%d ",path[v][i]);
dfs(path[v][i]);
}
}
}
void bfs(int v){
for(int i=0;i<path[v].size();++i){
if(!visit[path[v][i]]){
q.push(path[v][i]);
visit[path[v][i]]=1;
}
}
while(!q.empty()){
int t = q.front();
q.pop();
printf("%d ",t);
bfs(t);
}
}
int main(){
int x,y;
scanf("%d%d%d",&n,&m,&v);
for(int i=0;i<m;++i){
scanf("%d%d",&x,&y);
path[x].push_back(y);
path[y].push_back(x);
}
for(int i=0;i<n;++i)
sort(path[i].begin(),path[i].end());
visit[v]=1;
printf("%d ",v);
dfs(v);
puts("");
memset(visit,0,sizeof(visit));
visit[v]=1;
printf("%d ",v);
bfs(v);
}
#include<iostream>
using namespace std;
bool sola[100] = { false };
int direct(int a) {
//노드가 홀수일때
if (a % 2 == 1) {
//부모노드가 점유된 노드라면
if (sola[a / 2 - 1] == true) {
//a는 점유할수 없는 노드임
return a/2-1;
}
//부모노드가 점유되지 않은 노드라면
else {
sola[a] = true;
return 0;
}
}
//노드가 짝수일때
else {
if (sola[a / 2] == true) {
return a / 2;
}
else {
sola[a] = true;
return 0;
}
}
}
int main() {
int tree, input, bbi;
int answer[100] = {};
cin >> tree >> input;
for (int i = 0; i < input; i++) {
cin >> bbi;
answer[i + 1] = direct(bbi);
}
for (int i = 1; i <= input; i++) {
cout << answer[i] << endl;
}
}
#include<iostream>
#include<stack>
using namespace std;
bool node[1048577];
int main() {
int x, a;
cin >> x>> a;
for (int i = 0; i < a; i++) {
int input;
cin >> input;
bool judge = false;
int temp = input;
stack<int>answer;
//스택 넣기
while (temp!=0) {
answer.push(temp);
temp /= 2;
}
//스택 빼면서 점유된 땅 있는지 확인
while (!answer.empty()) {
temp = answer.top();
if (node[temp] == true) {
cout << temp << endl;
judge = true;
break;
}
else {
answer.pop();
}
}
if(judge==false){
node[input] = true;
cout << 0 << endl;
}
}
return 0;
}