2024 SDSC 提高班

模拟赛 #1

T1-risk

类原题:P3366 【模板】最小生成树

题意:给定 \(n\) 个点 \(m\) 条边的带权无向图,每个点上都有一定数量的军队,合并两个相邻点的军队的代价为边权 \(w\),求将所有的军队合并的最小代价。

不难发现最后的集结过程一定是一棵树,所以最小代价为此图的最小生成树的大小。

点击查看代码
int to[MAXN];
int go(int p){return (to[p]==p?p:to[p]=go(to[p]));} 

struct edge{
	int s,e,d;
}ed[MAXN];
 
int n,m;

bool cmp(edge a,edge b){
	return a.d<b.d;
}

signed main(){
	n=read(),m=read();
	for(int i=1;i<=m;i++)
		ed[i].s=read(),ed[i].e=read(),ed[i].d=read();
		
	std::sort(ed+1,ed+m+1,cmp);
	
	for(int i=1;i<=n;i++)
		to[i]=i;
		
	int ans=0;
	int cnt=0;
	for(int i=1;i<=m;i++){//最小生成树 
		if(cnt==n-1)break;
		int p1=ed[i].s,p2=ed[i].e,d=ed[i].d;
		if(go(p1)!=go(p2)){
			ans+=d;
			to[go(p1)]=go(p2);
			++cnt;
		}
	}

	println(ans);
	return 0;
}

T2-magic

原题:CF1346E Magic Tricks

首先考虑朴素的 DP,设 \(dp_{i,j}\) 表示在第 \(i\) 次操作后,关键球在 \(j\) 的最小花费。不难得到转移,\(dp_{i,x_i}=\min(dp_{i-1,x_i}+1,dp_{i-1,y_i}),dp_{i,y_i}=\min(dp_{i-1,y_i}+1,dp_{i-1,x_i})\)

发现每次转移第一维没有贡献,可以用滚动数组将第一维滚掉。

点击查看代码
int n,m,k,x,y,dp[MAXN];
signed main(){	
	n=read(),m=read(),k=read();
	
	memset(dp,0x3f,sizeof(dp));
	dp[k]=0;//dp 初始化 
	
	for(int i=1;i<=m;i++){
		x=read(),y=read();
		int nowx=dp[x],nowy=dp[y];//注意:先存下 dp[x],dp[y] 的值 
		dp[x]=std::min(nowx+1,nowy);
		dp[y]=std::min(nowx,nowy+1);//dp 的转移 
	}
		
	for(int i=1;i<=n;i++)
		put((dp[i]>m?-1:dp[i]),i,n);
	
	return 0;
}

T3-letters

原题:CF gym105214 E. Enumerating Substrings

注意特殊性质 所有字母出现次数都不超过两次,不难发现,该字符串的 border 一定不会超过字符串的一般且 border 存在的话有且只有一个。

考虑枚举 border 的长度,形式化地写成 ABA 的形式,则 A 中的字符在 B 中一定不会出现,所以只需要枚举 border。注意特判 \(|A|=0\) 的情况,容斥一下即可。

最后容斥一下不相交的情况即可。

T4-stars

原题:Baekjoon-23702 Three Dimensions

首先考虑特殊性质 my_a=my_b=mz_a=mz_b=0 的情况,则只需要考虑 \(|x_a-x_b|\)。设 \(f_{b,0/1,0/1,0/1/2/3,0/1}\) 表示考虑到第 \(b\) 位,是否满足 \(x_a\le mx_a\)\(x_b\le mx_b\)。并钦定 \(x_a,x_b\) 的大小。

posted @ 2024-09-01 07:08  CheZiHe929  阅读(57)  评论(0)    收藏  举报