CSP-J复赛准备 模板题

这篇博客整理了CSP-J复赛中常见的算法模板题目,包括最小生成树、单源最短路径的链式前向星和堆优化、并查集、树状数组的各种操作、线性筛、动态规划问题如01背包和完全背包,以及高精度运算和二叉树的相关算法,旨在帮助参赛者提升解题能力。
摘要由CSDN通过智能技术生成

CSP-J复赛准备 模板题

整理了一些有点难度的常用板子,希望
RP++

最小生成树

#include<bits/stdc++.h>
using namespace std;

const int MAX_M    = 200010;
const int MAX_NODE =  5010;

struct s{
   
	int a;
	int b;
	int z;
} con[MAX_M];

int father[MAX_NODE]; 
bool vis[MAX_NODE];


bool cmp(s a, s b){
   
	return a.z<b.z;
}

int find_root(int x) {
   
	if(father[x]!=-1) {
   
		return father[x] = find_root(father[x]);
	}
	return x;
}

/*
*	1: success 
*	0: fail
*/
int union_(int x, int y) {
   
	int x_root = find_root(x);
	int y_root = find_root(y);
	if(x_root!=y_root) {
   
		father[y_root] = x_root;
		return 1;
	}
	return 0;
} 

int main() {
   
	memset(father, -1, sizeof(father));
	
	int m, n, x, y, z, ans = 0;
	cin>>n>>m;
	for(int i=0; i<m; i++) {
   
		cin>>x>>y>>z;
		con[i].a = x;
		con[i].b = y;
		con[i].z = z;
	}
	sort(con, con+m, cmp);
	for(int i=0; i<m; i++) {
   
		if(union_(con[i].a, con[i].b)) {
   
			vis[con[i].a] = true;
			vis[con[i].b] = true;
			ans += con[i].z;
		}
	}
	for(int i=1; i<=n; i++) {
   
		if(!vis[i]) {
   
			cout<<"orz"<<endl;
			return 0;
		}
	}
	cout<<ans<<endl;
	return 0;
}

单源最短路径

链式前向星

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 10001;
const int MAXM = 500001;
const int INF  = 2147483647;

struct edge{
   
	int from;
	int to;
	int w;
	int next;
};
edge e[MAXM];

struct node{
   
	int w;
	int id;
	friend bool operator <(const node& a, const node& b) {
   
		return a.w>b.w;
	}
};

int cnt = 0;

int head[MAXN], vis[MAXN], m, n, s;

long long dis[MAXN];

void add(int from, int to, int w) {
   
	e[++cnt].from = from;
	e[cnt].to = to;
	e[cnt].w = w;
	e[cnt].next = head[from];
	head[from] = cnt;//head指from点的所有边 
}

priority_queue<node> q;
void dijkstra(int s) {
   
    for(int i=1;i<=n;i++) {
   
        dis[i]=INF;
    }
    dis[s]=0;//赋初值
    q.push((node){
   0,s});
    while(!q.empty()) {
   
        node x=q.top();
        q.pop();
        int u=x.id;
        if(vis[u])
			continue; 
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next) {
   
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].w) {
   
                dis[v]=dis[u]+e[i].w;
                q.push((node){
   dis[v],v});
            }
        }
    }
}
void printAns() {
   
	for(int i=1; i<=n; i++) {
   //从1开始 
		cout<<dis[i]<<" ";
	}
	cout<<endl;
}
int main() {
   
	cin>>n>>m>>s;
	int x, y, z;
	for(int i=0; i<m; i++) {
   
		cin>>x>>y>>z;
		add(x, y, z);
	}
	dijkstra(s);
	printAns();
	return 0;
}

堆优化

#include<bits/stdc++.h>
using namespace std;
/*我也不知道为什么用英文注释*/
const int maxn = 100010;//arr size too small will cause RE(seg fault)

typedef unsigned long long ull;

struct Edge{
   
    int from;
    int to;
    ull w;
};

struct Node{
   
    int n;
    ull w;
    friend bool operator < (const Node& a, const Node& b) {
   
        return a.w>b.w;
    }
};

int n, m, s = 1;

ull dis[maxn+1];

vector<Edge> edges;
vector<int > hea
对于一个数n,我们可以将其拆分成若干组数位相同的数字,然后读出每一组数字的数值和单位。例如: - 对于 123456789,我们可以将其拆分成 1 亿,2345 万,6789。 - 对于 200000,我们可以将其拆分成 2 十万。 具体的读法可以参考以下规则: - 对于 1~9 的数字,直接读出其汉字,如 1 读作“一”,9 读作“九”。 - 对于 10~99 的数字,读出十位数的汉字,如果个位数不为 0,则加上个位数的汉字,如 22 读作“二十二”,55 读作“五十五”。 - 对于 100~999 的数字,读出百位数的汉字,如果十位数为 0,则只读出“几百”,否则在“几百”后加上十位数和个位数的汉字,如 234 读作“二百三十四”,707 读作“七百零七”。 - 对于 1000~9999 的数字,读出千位数的汉字,如果百位数为 0,则只读出“几千”,否则在“几千”后加上百位数、十位数和个位数的汉字,如 5678 读作“五千六百七十八”。 - 对于 10000~99999 的数字,读出万位数的汉字,如果千位数为 0,则只读出“几万”,否则在“几万”后加上千位数、百位数、十位数和个位数的汉字,如 12345 读作“一万二千三百四十五”。 - 对于 100000~999999 的数字,读出十万位数的汉字,如果万位数为 0,则只读出“几十万”,否则在“几十万”后加上万位数、千位数、百位数、十位数和个位数的汉字,如 234567 读作“二十三万四千五百六十七”。 - 对于 1000000~99999999 的数字,读出百万位数的汉字,如果十万位数为 0,则只读出“几百万”,否则在“几百万”后加上十万位数、万位数、千位数、百位数、十位数和个位数的汉字,如 12345678 读作“一千二百三十四万五千六百七十八”。 - 对于 100000000~999999999 的数字,读出亿位数的汉字,如果百万位数为 0,则只读出“几亿”,否则在“几亿”后加上百万位数、十万位数、万位数、千位数、百位数、十位数和个位数的汉字,如 987654321 读作“九亿八千七百六十五万四千三百二十一”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值