일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 비트마스크
- boj
- BFS
- 세그먼트트리
- 다익스트라
- 그리디
- 위상정렬
- 에라토스테네스의 체
- 브루트포스
- 정렬
- 좌표압축
- 누적합
- 삼분탐색
- 수학
- 이분매칭
- LazyPropagation
- MST
- dfs
- 플로이드와샬
- 펜윅트리
- lca
- DP
- 구현
- 이분탐색
- DisjointSet
- 백준
- lis
- 이진탐색
- 투포인터
- 크루스칼
Archives
- Today
- Total
lastknight00
[백준]헤븐스 키친(14574) 본문
문제 링크 : [백준]헤븐스 키친(14574)
문제 설명
N명의 참가자가 있고, 서로 경쟁을 하면서 이긴 사람을 떠나고, 패한 사람이 계속 경쟁을 이어갑니다.
N-1번의 게임을 이어가면서 시청률의 합을 최대로 하기 위하여 승자와 패자를 어떻게 결정해야 하는지, 그 때의 시청률이 몇인지 출력하세요.
입력
N(참가자 수, 1 <= N <= 1,000)
Pi(요리사의 실력, 0 <= Pi <= 1,000,000,000)
Ci(요리사의 인기도, 0 <= Ci <= 1,000,000,000)
3
1 2
3 1
5 3
출력
3
2 1
3 2
카테고리
#DFS #MST #크루스칼
시간 복잡도 상한
O(N2logN2)
해결 방법
- 토너먼트를 생각하면 접근이 조금 쉽습니다.
- 특이한 점은 진 사람이 계속 게임을 이어나가는데, 결국은 일반적인 토너먼트와 유사한 모양이 될 것입니다.
- 그리고 토너먼트는 트리로 구성이됩니다.
- 1명이 남을 때 까지 경쟁이 이어지기 때문에, N-1번의 경쟁이 이루어지고, 한 번 이긴 사람은 떠나기 때문에 싸이클이 발생할 수도 없습니다.
- 결국 트리 모양인 것입니다.
- 그 중에 트리를 구성하는 간선을 시청률로 보게 되면 최대 스패닝 트리로 시청률 합의 최대값을 구할 수 있습니다.
- 그리고 MST를 구하면서 선택 된 간선들을 가지고 인접리스트를 구성합니다.
- 이긴 사람이 떠나는 구조이기 때문에, DFS로 리프 노드까지 방문하고, 리프 노드가 승자, 부모가 패자가 되면, 문제에서 요구하는 답을 구할 수 있습니다.
시간복잡도
O(N2logN2)
코드
#include<cstdio>
#include<algorithm>
#include<vector>
#define N 1001
#define F second.first
#define S second.second
using namespace std;
typedef pair<int,pair<int,int>>P;
int n,d[N][2],i,j,g[N];
long long s;
vector<P>v;
vector<int>w[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);}
void r(int p,int u){
for(int x:w[p])if(x!=u)r(x,p);
if(u)printf("%d %d\n",u,p);
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)g[i]=i,scanf("%d%d",d[i],d[i]+1);
for(i=1;i<n;i++)for(j=i+1;j<=n;j++)v.push_back({(d[i][1]+d[j][1])/abs(d[i][0]-d[j][0]),{i,j}});
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
for(P x:v){
if(f(x.F)!=f(x.S)){
s+=x.first;
w[x.F].push_back(x.S);
w[x.S].push_back(x.F);
u(x.F,x.S);
}
}
printf("%lld\n",s);
r(1,0);
}
'PS' 카테고리의 다른 글
[백준]빌보의 생일(4442) (0) | 2020.09.10 |
---|---|
[백준]중복 제거(13701) (0) | 2020.09.09 |
[백준]핑크 플로이드(6091) (0) | 2020.09.08 |
[백준]퀘스트 중인 모험가(15816) (0) | 2020.09.05 |
[백준]여러 직사각형의 전체 면적 구하기(2672) (0) | 2020.09.04 |
Comments