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;
}
posted @ 2022-08-15 19:37  Star_LIcsAy  阅读(52)  评论(0)    收藏  举报