일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- lis
- 투포인터
- BFS
- 비트마스크
- 정렬
- 백준
- 구현
- 수학
- 위상정렬
- 브루트포스
- 다익스트라
- 에라토스테네스의 체
- boj
- LazyPropagation
- DisjointSet
- 삼분탐색
- 펜윅트리
- dfs
- 그리디
- 플로이드와샬
- 세그먼트트리
- 이분매칭
- lca
- 이분탐색
- DP
- 좌표압축
- MST
- 누적합
- 이진탐색
- 크루스칼
Archives
- Today
- Total
lastknight00
[백준]핑크 플로이드(6091) 본문
문제 링크 : [백준]핑크 플로이드(6091)
문제 설명
N개의 노드간의 최단거리가 인접행렬로 주어 질 때, 인접 리스트로 변형하여 출력하세요.
입력
N(노드의 갯수, 1 <= N <= 1,024)
Vij(i에서 j까지의 최단거리)
5
5 14 3 7
13 2 6
11 7
4
출력
1 4
1 4
1 5
3 1 2 5
2 3 4
카테고리
#MST #크루스칼
시간 복잡도 상한
O(N2logN)
해결 방법
- 모든 간선 중 비용이 가장 작은 간선은 항상 두 노드를 직접 잇는 간선이 됩니다.
- 그렇게 찾은 간선을 간선 리스트에 저장합니다.
- 1번에서 선택한 간선을 제외하고 나머지 간선 들 중 가장 작은 간선을 살펴봅니다.
- 이때 그 간선의 양 끝 노드가 이미 더 작은 비용 간선들로 이어져있다면, 그 간선은 플로이드 와샬 알고리즘에 의해 만들어진 중간 지점을 경로하는 간선이 됩니다.
- 1~4까지의 과정을 보면 크루스칼과 동일함을 알 수 있습니다.
- 즉 플로이드 와샬 알고리즘을 돌리면서, Disjoint Set에서 두 노드가 같은 그룹에 있다면 continue, 그렇지 않다면 인접리스트에 정보를 저장하면 됩니다.
시간복잡도
O(N2logN2)
코드
#include<iostream>
#include<algorithm>
#include<vector>
#define F second.first
#define S second.second
#define N 1025
using namespace std;
typedef pair<int,pair<int,int>>P;
int n,i,j,c,g[N];
vector<P>v;
vector<int>a[N];
int f(int x){return x==g[x]?x:g[x]=f(g[x]);}
void u(int x,int y){g[f(x)]=f(y);}
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(i=1;i<=n;i++)for(g[i]=i,j=i+1;j<=n;j++)cin>>c,v.push_back({c,{i,j}});
sort(v.begin(),v.end());
for(P x:v){
if(f(x.S)!=f(x.F)){
a[x.F].push_back(x.S);
a[x.S].push_back(x.F);
u(x.F,x.S);
}
}
for(i=1;i<=n;i++){
cout<<a[i].size();
sort(a[i].begin(),a[i].end());
for(int x:a[i])cout<<" "<<x;
cout<<"\n";
}
}
'PS' 카테고리의 다른 글
[백준]중복 제거(13701) (0) | 2020.09.09 |
---|---|
[백준]헤븐스 키친(14574) (0) | 2020.09.08 |
[백준]퀘스트 중인 모험가(15816) (0) | 2020.09.05 |
[백준]여러 직사각형의 전체 면적 구하기(2672) (0) | 2020.09.04 |
[백준]컨닝(1014) (0) | 2020.09.01 |
Comments