인접 행렬
- V^2개의 원소를 가진 2차원배열.
인접 리스트
- V개의 연결리스트( 동적 배열 )
- vector기반이라 느리다.
- 간선 번호 붙일 때 불편하다 ( 순회하기 힘들다. )
간선 배열
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> pint;
#define x first
#define y second
const int maxv = 100000, maxe = 200000;
pint edge[maxe]; // 배열의 각 주소는 (x, y) 튜플 페어를 가짐.
int st[maxv]; // 간선을 정렬한 후, 각 점에서 시작하는 간선의 첫 인덱스
int v, e;
int main() {
// Input
cin >> v >> e;
for (int i=1; i<=e; i++)
cin >> edge[i].x >> edge[i].y;
// Processing
sort(edge+1, edge+e+1);
st[v+1] = e+1;
for (int i=1, k=1; i<=e; i++)
while (edge[i].x >= k) st[k++] = i;
// Output
for (int i=1; i<=v; i++)
for (int j=st[i]; j<st[i+1]; j++)
cout << i << " and " << edge[j].y << " are connected.\n";
}
- 간선을 시작점, 끝점 순서로 정렬.
- 그리고 각 정점에서 시작하는 간선을 찾기위해 st배열에 시작간선, 끝간선을 저장.
- (st[i] ~ st[i+1] - 1 번 간선은 i에서 시작)
- 이걸 쓰면 인접리스트의 단점인 간선을 순회하기 불편하다는 단점을 보완할 수 있다.
- O(ElogE)
간선 리스트
#include <iostream>
#include <algorithm>
using namespace std;
const int maxv = 100000, maxe = 200000;
int a[maxe], b[maxe], nxt[maxe], st[maxv], p = 2;
void add(int x, int y) {
a[np] = x; b[np] = y; nxt[np] = st[x]; st[x] = p++;
}
int v, e;
int main() {
cin >> v >> e;
for (int i=1; i<=e; i++) {
int x, y;
cin >> x >> y;
add(x, y);
}
for (int i=1; i<=v; i++)
for (int j=st[i]; j; j=nxt[j])
cout << a[j] << " and " << b[j] << " are connected.\n";
}
- 인접배열에서 배열을 연결 리스트로 바꾼 방법.
- 각 정점은 자신과 연결된 간선들을 저장하는 ㅇ녀결 리스트를 하나씩 가지고 있고 연결리스트들은 하나의 배열안에 모두 들어있다. 연결리스트는 다음 원소의 포인터가 아닌 다음 원소의 배열에서의 인덱스를 가지고 있다.
- 즉 1. 간선을 저장한느 배열, 2. 각 정점에서 연결되는 간선들을 저장하는 연결리스트 로 이루어져있다.
- 그래프를 정점, 간선 두가지 요소로 분리해 사용.
- O(E)
#include <iostream>
using namespace std;
const int maxv = 100000, maxe = 200000;
int a[maxe], b[maxe], w[maxe], nxt[maxe], st[maxv], p = 2;
void add(int x, int y, int wt) {
a[np] = x; b[np] = y; w[np] = wt; nxt[np] = st[x]; st[x] = p++;
}
int v, e;
int main() {
cin >> v >> e;
for (int i=1; i<=e; i++) {
int x, y, w;
cin >> x >> y >> w;
add(x, y, w);
}
for (int i=1; i<=v; i++)
for (int j=st[i]; j; j=nxt[j])
cout << a[j] << " and " << b[j] << " are connected in weight " << w[j] << ".\n";
}
- 유량 알고리즘은 역간선을 쉽게 구해야 하는데 간선과 역간선을 리스트의 인접한 인덱스에 넣어두면 쉽게 역간선에 접근 할 수 있다. 위에서 i번 간선의 역간선은 i^1번 간선이다(xor)
- 무방향 그래프에서 홀짝을 맞추기위해 초기 p=2
- 간선 순서를 섞어주어야 하는 상황에서는 쓰면 안된다(크루스칼)
Reference
https://blog.junie.land/11 [프로그래밍 연습장]
'practivceAlgorithm > 자료구조&알고리즘' 카테고리의 다른 글
[자료구조] 파이썬으로 LRU cache O(1) 구현하기 (0) | 2022.07.25 |
---|---|
[자료구조 & 알고리즘] Hash 함수와 충돌 Map, Set, Table 구현체 (0) | 2021.11.04 |
[Algorithm] 0 - 1 Knapsack 문제와 DP 기본 (0) | 2021.10.23 |
[알고리즘] 중복조합 (0) | 2021.09.18 |
[알고리즘] 편집거리 알고리즘 : 두 문자열의 유사도를 판단 (0) | 2021.09.14 |