2022/8/15 总结
题单贴贴
A.Begin
- 这是道结论题。但令人惊奇的是我
完全没往这方面想用奇怪的策略做居然得到了 \(\mathtt{80pts}\);
Solution
-
观察样例,再结合一点数学知识,我们可以知道当每一对 \(a\) 和 \(b\) 相差尽可能小的时候,答案有最小值。考虑排序,但 \(min\) 值与 \(max\) 值这一对产生的贡献很可能巨大,所以要避免这种情况的发生。
-
得到结论为将 \((w_1,w_2)\)、\((w_{n-1},w_n)\) 连接,对于 \(i\in [1,n-2]\),将每一对 \((w_i,w_{i+2})\) 相连即可;
AC code
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int s=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
s=s*10+int(ch-'0');
ch=getchar();
}
return s*f;
}
#define ll long long
const int N=1e6+10;
int n;
int w[N];
ll ans=0;
int main(){
n=read();
for(int i=1;i<=n;++i)
w[i]=read();
sort(w+1,w+n+1);
ans+=1ll*(w[1]-w[2])*(w[1]-w[2])+1ll*(w[n-1]-w[n])*(w[n-1]-w[n]);
for(int i=1;i<n-1;++i)
ans+=1ll*(w[i]-w[i+2])*(w[i]-w[i+2]);
printf("%lld",ans);
return 0;
}
B.Arrive
- 也算半个结论题吧
(我是跟结论题有仇吗一道都看不出来);
Solution
-
观察样例,再自己手模一下可以发现,如果能够成功匹配,那么一定是两两一组,互为对方庇护所,因此当 \(n\) 为奇数时,可以直接排除;
-
\(\mathtt{dfs}\) 一遍这棵树,将所有节点的匹配点找出来。如果有 多个点试图与某点匹配/根节点找不到匹配对象等情况,说明不能匹配,排除;
-
排除错误答案之后,新建一个图,将每个点与它的匹配点连接的点相连(除了它自己),建立有向边 \(u→v\) 表示 \(u<v\),表示大小关系。统计每个点的入度,将所有入度为 \(0\) 的点加入优先队列,因为字典序要求最小,所以编号较小的点先出列;
-
统计每个点的位置,将新图中每个被它指向的点的入度 \(-1\),再将后来的点放进优先队列中。当所有点都入队出队一遍后答案就统计完成了。
AC code
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int s=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
s=s*10+int(ch-'0');
ch=getchar();
}
return s*f;
}
const int N=5e5+10;
const int Inf=0x3f3f3f3f;
int n;
int d[N],siz[N];
int head[N],ver[N<<1],nxt[N<<1],tot=0;
int pt[N],val[N],k=0;
bool ans=1;
priority_queue<int>q;
vector<int>edge[N];
void add(int u,int v){
ver[++tot]=v;
nxt[tot]=head[u],head[u]=tot;
return ;
}
void dfs(int p,int f){
if(!ans) return ;
siz[p]=1;
int cnt=0;
for(int i=head[p];i;i=nxt[i]){
if(ver[i]==f) continue;
dfs(ver[i],p);
if(siz[ver[i]]%2){
pt[p]=ver[i];
++cnt;
if(cnt>1)
ans=0;
}
siz[p]+=siz[ver[i]];
}
if(siz[p]%2)
pt[p]=f;
if(!ans) return ;
for(int i=head[pt[p]];i;i=nxt[i]){
if(ver[i]==p) continue;
edge[p].push_back(ver[i]);
++d[ver[i]];
}
for(int i=head[p];i;i=nxt[i]){
if(ver[i]==pt[p]) continue;
edge[pt[p]].push_back(ver[i]);
++d[ver[i]];
}
return ;
}
int main(){
n=read();
int u,v;
bool p2=1;
for(int i=1;i<n;++i){
u=read(),v=read();
add(u,v);
add(v,u);
}
dfs(1,0);
if(!ans || n%2!=0){
printf("-1");
return 0;
}
for(int i=1;i<=n;++i)
if(!d[i])
q.push(-i);
while(q.size()){
int x=-q.top();
q.pop();
val[++k]=x;
for(int i=0;i<edge[x].size();++i){
--d[edge[x][i]];
if(!d[edge[x][i]])
q.push(-edge[x][i]);
}
}
for(int i=1;i<=n;++i)
printf("%d ",val[i]);
return 0;
}

浙公网安备 33010602011771号