后续会继续更新的
迪杰斯特拉(未优化)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=0x3f3f3f3f;
int mp[1005][1005];
int n,m,s;
int ans;
int dis[1005]={-1},vis[1005];
//迪杰斯特拉函数
void dij(int n,int s){
//将所有的点距离设置为无穷
for(int i=0;i<=n;i++){
dis[i]=N;
}dis[s]=0;//s为起点,s到s的点的距离为0
//遍历所有的点
for(int i=1;i<=n;i++){
int u=0;//认为当前距离最短的点为0
for(int j=1;j<=n;++j){
if(!vis[j] and dis[j] < dis[u])u=j;//如果这个点没有选定且当为j点的距离比u的距离更短,对最短路径u点更新
}vis[u]=1;//选定了u点,对u点进行标记
for(int j=1;j<=n;j++){//遍历检查所有点
if(mp[u][j]){//如果u到j点有边
int w = mp[u][j];//获取u点到j点的距离
if(dis[j]>dis[u]+w){//检查如果u点到j点的距离,小于原本j点的距离
dis[j]=dis[u]+w;//将到j点的距离数组更新。
}
}
}
}
}
signed main(){
cin >> n >> m >> s;
for(int i=1;i<=m;i++){
int u,v,w;
cin >> u >> v >> w;
int tmp=mp[u][v]?mp[u][v]:N;//邻接矩阵储存图,如果该位置,没有边则设置为无限(既0x3f3f3f3f)。否则为原本的边与当前边的较小者。
mp[u][v]=min(tmp,w); //人话就是处理重边
}dij(n,s);//函数调用,n为点的个数,s为起点
for(int i=1;i<=n;i++){//依次输出所有点从起点s的最短路径
if(dis[i]==N)cout << -1 << " "; //不能到达则输出-1
else cout << dis[i] << " ";//能到达输出最短路径
}
return 0;
}
优化版本(优先队列)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=0x3f3f3f3f3f3f3f;
int mp[1005][1005];
int n,m,s;
int dis[1005],vis[1005];
void dij(int n,int s){
for(int i=1;i<=n;i++){
dis[i]=N;
}
dis[s]=0;
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> heap;
heap.push({0,s});
while(!heap.empty()){//主循环
int u=heap.top().second;
heap.pop();
if(vis[u])continue;
vis[u]=1;
for(int j=1;j<=n;j++){
if(mp[u][j]){
int w=mp[u][j];
if(dis[j]>dis[u]+w){
dis[j]=dis[u]+w;
heap.push({dis[j],j});
}
}
}
}
}
signed main(){
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
int tmp=mp[u][v]?mp[u][v]:N;//重边
mp[u][v]=min(tmp,w);
}dij(n,s);
for(int i=1;i<=n;i++){
if(dis[i]==N)cout<<-1<<" ";
else cout<<dis[i]<<" ";
}
return 0;
}
贝尔曼福特
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int from,to,len;//出发点,要去的点,长度
}a[10010];
int n,m,s,t;//依托不知名的东西,分别是节点数,边数,起点,终点
int dis[10010] ;
signed main(){
cin >> n >> m >> s >> t;
for(int i=1;i<=n;i++){
dis[i] = 1e9; //初始化数组
}
dis[s]=0;//起点
for(int i=1;i<=m;i++){
cin >> a[i].from >> a[i].to >> a[i].len;//输入图的相关数据
}
int from,to,len;//出发点,要去的点,长度
for(int k=1;k<n;k++){
bool p=false;
for(int i=1;i<=m;i++){
from=a[i].from,to=a[i].to,len=a[i].len;//赋值。
if(dis[to]>dis[from]+len){
p=true;
dis[to]=dis[from]+len;
}
//判断走到to这个点能否更新最短距离
}if(p==false)break;
}
cout << dis[t];
//输出走到t的最短路径
return 0;
}
SPFA
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,s,t;
int dis[10010],vis[10010],mp[5010][5010];
signed main(){
cin >> n >> m >> s >>t;
for(int i=1;i<=n;i++){
dis[i]=1e9; //初始化数组
}for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
mp[i][j]=1e9;//初始化*2
}
}for(int i = 1;i <= m;i++){
int s,t,v;
cin >> s >> t >> v;
mp[s][t]=v;//输入图并储存
}dis[s]=0;
vis[s]=1;
queue<int> a;
a.push(s);
while(a.size()){
int u=a.front();//取出队首
a.pop();//取出
vis[u]=0;//将该点标记为不在队列中
for(int i=1;i<=n;i++){
if(dis[i]>dis[u]+mp[u][i]){
dis[i]=dis[u]+mp[u][i];//更新,进行松弛操作
if(!vis[i]){//如果该点被更改
vis[i]=1; //标记
a.push(i);//入队
}
}
}
}
cout << dis[t];
return 0;
}
弗洛伊德
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;//计数器
int dis[101][101],a[10001];//距离数组及必经之路数组
int main(){
cin >> n >> m;
for(int i=1;i<=m;i++)cin >> a[i];//输入必经之路
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin >> dis[i][j];//输入距离
}
}for(int k=1;k<=n;k++){//中转点
for(int i=1;i<=n;i++){//在邻接矩阵的x坐标
for(int j=1;j<=n;j++){ //在邻接矩阵的y坐标
dis[i][j]=min(dis[i][j],dis[k][j]+dis[i][k]);//松弛操作
}
}
}for(int i=2;i<=m;i++){
ans+=dis[a[i-1]][a[i]];//计数
}cout << ans;
return 0;
}
归并排序:
#include<iostream>
using namespace std;
int n,a[1010],temp[1010];
void MergeSort(int l,int r){
//2.1、递归的结束条件:只有一个数,就不用再递归下去,直接返回
if(l==r){
return ;
}
//2.2、找到中间位置,递归处理左半部分,递归处理右半部分
int mid=(l+r)/2;
MergeSort(l,mid);
MergeSort(mid+1,r);
//3、合并,两个序列分别为[l,mid] 和 [mid+1,r],从最左边开始,依次比较,小的数放入结果数组temp,下标右移
int i=l,j=mid+1,k=l;
while(i<=mid and j<=r){
if(a[i]<=a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
//3.1、判断两个序列是否有剩余,有剩余的,全部放入结果数组 temp
while(i<=mid)
temp[k++]=a[i++];
while(j<=r)
temp[k++]=a[j++];
//4、把结果数组 temp 重新赋给 a 数组
for(int i=l;i<=r;i++)
a[i]=temp[i];
}
int main(){
//1、定义变量 n 和数组
cin >> n;
for(int i=1;i<=n;i++)
cin >> a[i];
//2、划分,左端点为 1,右端点为 n,递归处理
MergeSort(1,n);
for(int i=1;i<=n;i++)
cout << a[i]<<" ";
return 0;
}
快速排序
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
int a[N];
int n;
void partition(int a[],int l,int r){
int x=a[l],i=l,j=r;
if(l>=r) return;
while(i<j) {
while(i<j and a[j]>=x) j--;
a[i]=a[j];
while(i<j and a[i]<=x) i++;
a[j]=a[i];
}a[i]=x;
partition(a,l,i-1);
partition(a,i+1,r);
}
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
partition(a,0,n-1);
for(int i=0;i<n;i++)cout << a[i]<<" ";
return 0;
}
埃氏筛
#include <bits/stdc++.h>
using namespace std;
int main(){
int a;
cin >> a;
int sz[10000005]={0};
sz[1]=1;
for(int i=1;i*i<=a;i++){
if(sz[i]==0){
for(int j=2*i;j<=a;j+=i){
sz[j]=1;
}
}
}for(int i=1;i<=a;i++){
if(sz[i]==0){
cout << i << " ";
}
}
return 0;
}
欧拉筛
#include <bits/stdc++.h>
using namespace std;
#define int long long
int sz[10000005];
int prime[10000005];
signed main(){
int a;
cin >> a;
int cnt = 0;
sz[1] = 1;
for(int i=2;i<=a;i++){
if(sz[i]==0){
prime[cnt++] = i;
}for(int j=0;j<cnt and i*prime[j]<=a;j++){
sz[i*prime[j]] = 1;
if(i%prime[j]==0){
break;
}
}
}for(int i=1;i<=a;i++){
if(sz[i]==0){
cout << i << " ";
}
}
return 0;
}
最长上升子序列(lis)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int sz[1005]={},lis[1005]={};
signed main(){
int a;
cin >> a;
for(int i=1;i<=a;i++){
cin >>sz[i];
}for(int i=1;i<=a;i++){//lis
lis[i]=1;
for(int j=1;j<i;j++){
if(sz[j]<sz[i]){
lis[i]=max(lis[i],lis[j]+1);
}
}
}
cout << lis[a];
return 0;
}
最长下降子序列(lds)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int sz[1005]={},lds[1005]={};
signed main(){
int a;
cin >> a;
for(int i=1;i<=a;i++){
cin >>sz[i];
}for(int i=1;i<=a;i++){//lds
lds[i]=1;
for(int j=1;j<i;j++){
if(sz[j]>sz[i]){
lds[i]=max(lds[i],lds[j]+1);
}
}
}
cout << lds[a];
return 0;
}
堆的实现简易版(STL,作者刚开始自学):
#include <bits/stdc++.h>
using namespace std;
priority_queue<int, vector<int>, greater<int>> heap;//小根堆
vector<int> a;//输入
int main(){
int x;
heap.top();//取堆顶元素
heap.pop();//删除堆顶元素
heap.push(x);//将元素 x 插入堆
heap.size();//堆的大小
heap.empty();//判空
return 0;
}
堆的数组实现(可能有点AI风,因为用了下AI修正)
#include <bits/stdc++.h>
using namespace std;
class MinHeap{
private:
vector<int> heap; // 用vector存储堆数据,索引0作堆顶
void heapifyUp(int index){// 上浮调整
while(index>0) {
int parent=(index-1)/2; // 计算父节点索引
if(heap[index]>=heap[parent]) break; // 如果当前节点>=父节点,满足堆性质,退出
swap(heap[index],heap[parent]); // 否则交换父子节点
index=parent; // 向上检查
}
}
void heapifyDown(int index){// 下沉调整
int size=heap.size();
while(1) {
int left=2*index+1; // 左孩子索引
int right=2*index+2; // 右孩子索引
int smallest=index; // 假设当前节点最小
if(left<size and heap[left]<heap[smallest]) // 找当前节点和左右孩子中最小的
smallest=left;
if(right<size and heap[right]<heap[smallest])
smallest=right;
if(smallest==index) break; // 如果当前节点就是最小的,堆性质满足
swap(heap[index], heap[smallest]); // 否则交换
index = smallest; // 向下检查
}
}
public:
void push(int value){// 插入元素:先放到末尾,然后上浮调整
heap.push_back(value);
heapifyUp(heap.size()-1);
}// 删除堆顶:用最后一个元素替换堆顶,然后下沉调整
void pop() {
if(heap.empty()) return; // 空堆直接返回
heap[0]=heap.back(); // 末尾元素移到堆顶
heap.pop_back(); // 删除末尾元素
if(!heap.empty()) heapifyDown(0); // 如果堆不为空,从堆顶开始下沉
}// 获取堆顶元素(最小值)
int top(){
return heap.empty()?-1:heap[0]; // 空堆返回-1,否则返回堆顶
}// 判断堆是否为空
bool empty(){
return heap.empty();
}// 获取堆大小
size_t size(){
return heap.size();
}
};
int main() {
MinHeap heap;
int n;
cin >> n;
return 0;
}
大家觉得咋样
写的还行
一般般



