CSP-J复赛准备 模板题

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值