To_Heart—题解——AGC059 B
居然是B题?但是但是还是感觉很难,,,
题意
但是翻译错了一点,就是所求并不是有序二元组,而是 (a,b) 满足 a<b
题解
假设一共有 m 种颜色。
首先考虑将同一个颜色抽象成一个点,,因为最后连出来一个环,所以所有颜色节点联通。
那么反过来想,一组数据的答案不可能小于 m-1。
然后我们把所有颜色相同的放在一起,答案就是 m。所以一组数据的答案不可能超过 m。
所以我们只需要考虑什么时候答案可以是 m-1。
#include<bits/stdc++.h>
using namespace std;
int sum[200005];
int du[200005];
int qwq[200005];
int lsh[200005];
int id[200005];
int a[200005];
vector<int> v[200005];
int m=0,n;
bool cmp(int x,int y){
return sum[x]<sum[y];
}
void DFS(int x,int fa){
for(auto y:v[x]) if(y^fa) printf("%d ",qwq[x]),DFS(y,x);
for(int i=1;i<=du[x]-v[x].size();i++) printf("%d ",qwq[x]);
if(fa) printf("%d ",qwq[x]);
}
int main(){
int T;cin>>T;
while(T--){
for(int i=1;i<=n;i++) lsh[a[i]]=0;
scanf("%d",&n);m=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) v[i].clear(),lsh[i]=du[i]=sum[i]=qwq[i]=0;
// for(int i=1;i<=n;i++) printf("%d ",a[i]);
// printf("\n");
for(int i=1;i<=n;i++){
if(!lsh[a[i]]) m++,qwq[m]=a[i],lsh[a[i]]=m;
sum[lsh[a[i]]]++,du[lsh[a[i]]]++;
}
// printf("%d %d\n",n,m);
for(int i=1;i<=m;i++) id[i]=i;
sort(id+1,id+m+1,cmp);
if((m-1)*2>n||m==1){
for(int i=1;i<=n;i++) printf("%d ",a[i]);
printf("\n");continue;
}
// printf("qwq\n");
int l=1,r=0;
for(int i=1;i<=m;i++) if(sum[id[i]]>=2){ r=i;break; }
// printf("qwq::%d %d\n",l,r);
while(l<m-1){
// printf("qwqqwq::%d %d\n",l,r);
if(l==r){ sum[id[r]]=1;r++;continue; }
if(sum[id[r]]==1){ r++;continue; }
int x=id[l],y=id[r];
v[x].push_back(y),v[y].push_back(x);
sum[id[r]]--,l++;
}
v[id[m]].push_back(id[m-1]),v[id[m-1]].push_back(id[m]);
// for(int i=1;i<=m;i++){
// int x=id[i];
// printf("%d->%d::",x,qwq[x]);
// for(auto y:v[x]) printf("(%d->%d) ",y,qwq[y]);
// printf("\n");
// }
DFS(id[m],0);
printf("\n");
}
return 0;
}
/*
最高是 m
最低是 m-1
所以不是 m 就是 m-1
*/