题解:CF1283F DIY Garland
jinminghao · · 题解
清新小构造。
显而易见
一根导线的重要性是如果切断这根导线所有因此与电源断开的灯的亮度值之和,相当于是这根导线连接的儿子的子树亮度和。
又因为第
所以一根导线的重要性也相当于这个导线所连儿子的子树的彩灯最大值(最大值相等则深度越深重要性越小)。
然后又因为导线重要性是所连儿子子树的彩灯最大值,所以题目给的
我的思路大概是这样:扫描
如果
如果
如果
代码:
#include<bits/stdc++.h>
#define ft first
#define sd second
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int a[N],len,n;
bool st[N];
PII ans[N];
priority_queue<int,vector<int>,less<int>> q;
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
q.push(i);
}
int fa=a[1];
st[a[1]]=true;
for(int i=2;i<n;i++){
while(q.size()&&st[q.top()]) q.pop();
// printf("q[%d].top() = %d\n",i,q.top());
// if(i==4) printf("st[5] = %d\n",st[5]);
if(st[a[i]]){
ans[++len]={fa,q.top()};
st[q.top()]=true;
q.pop();
// if(i==3) printf("q.top() = %d\n",q.top());
fa=a[i];
}else{
ans[++len]={fa,a[i]};
st[a[i]]=true;
fa=a[i];
}
}
while(q.size()){
if(st[q.top()]){
q.pop();
continue;
}
ans[++len]={fa,q.top()};
st[q.top()]=true;
fa=q.top();
q.pop();
}
if(len!=n-1){
puts("-1");
return 0;
}
printf("%d\n",a[1]);
for(int i=1;i<=len;i++){
printf("%d %d\n",ans[i].ft,ans[i].sd);
}
return 0;
}