蓝桥杯备赛 Day 21 图论基础
图的基础
![[图的基础.png]]
1.图的存储方式
(1)邻接表(常用)
vector<pair<int,int>> g[N]; //g[x]存放x的所有出点信息,二维数组
g[i][j]={first,second},first是从i出发的第j个出点,second表示边权
例如上图:
g[1]={{2,0}.{3,0}}
g[6]={{3,7}}
g[4]={{5,0},{6,0}}
for(auto &y:g[x])
(2)邻接矩阵
d[i][j]表示i到j的边的距离,不存在为inf(无穷)
例如上图:
d[1][2]=0
g[6][3]=7
g[4][3]=inf
所以对于每个i,都要枚举所有j(1-n),判断是不是无穷
遍历图
DFS
//使用bistset<N>比bool数组更好
bitset<N> vis;//vis[i]=true说明i已经走过
void dfs(int x){vis[x]=true;for(const auot &y:g[x]){if(vis[y]) continue;dfs(y);}
}
BFS
bitset<N> vis;//vis[i]=true说明i已经走过
queue<int> q;//q表示待拓展的点队列
q.emplace(1);
while(q.size()){//只要队列不为空int x=q.front();q.pop();if(vis[x]) continue;vis[x]=true;//放入同一层的结点for(const auto& y:g[x]) q.emplace(y);
}
3891帮派弟位
学习:
1.此题利用树就能写,DFS更新子树数组sz,然后自定义排序cmp即可
2.因为无需换根,所有邻接表只要存储题目表示的父子关系即可
g[v].emplace_back(u);
代码:
#include <bits/stdc++.h>using namespace std;
const int N=1e5+10;
vector<int> g[N]; //邻接表
int sz[N]; //子树
int n,m; void dfs(int x,int f){sz[x]=1;//遍历儿子for(const auto &y:g[x]){if(y==f) continue;dfs(y,x);sz[x]+=sz[y];}
}//自定义排序
bool cmp(int &x,int &y){//先按子树大小if(sz[x]!=sz[y]) return sz[x]>sz[y];//再按序号return x<y;
} int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=n-1;i++){int u,v;cin>>u>>v;//g[u].emplace_back(v); //无需存储g[v].emplace_back(u);}dfs(1,0);//排序vector<int> ans;for(int i=1;i<=n;i++) ans.emplace_back(i);sort(ans.begin(),ans.end(),cmp); for(int i=0;i<n;i++){if(ans[i]==m){cout<<i+1;break;}}return 0;
}
3352可行路径的方案数
学习:
1.此题为图例中的最短路径问题,不适合深度搜索DFS,而应该用层序搜索BFS,使用队列实现
2.开一个最短距离数组dist,最短距离的路径数量数组cnt
3.不要vis数组,因为一个点会访问多次
代码:
#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int N=2e5+10,mod=1e9+7;
vector<int> g[N]; //邻接表
ll dist[N]; //1到i的最短距离数组
ll cnt[N]; //1到i的最短距离的路径和数组
int n,m;void bfs(){//创建队列queue<int> q;//从1开始q.emplace(1);dist[1]=0;cnt[1]=1;//开始bfs while(!q.empty()){int x=q.front();q.pop();//遍历for(const auto &y:g[x]){//未访问过,肯定最小,因为是bfsif(dist[y]==-1){//y从x访问过来 dist[y]=dist[x]+1;//y的路径数和x的路径数一样 cnt[y]=cnt[x];//放入y q.emplace(y);} //访问过,且等于最短的else if(dist[y]==dist[x]+1){//y的路径数再加上x的路径数cnt[y]=(cnt[y]+cnt[x])%mod; } } }
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=m;i++){int a,b;cin>>a>>b;g[a].emplace_back(b);g[b].emplace_back(a);}//初始化d,cntmemset(dist,-1,sizeof(dist));memset(cnt,0,sizeof(cnt)); bfs();cout<<cnt[n];return 0;
}
拓扑排序
![[拓扑排序.png]]
学习
1.针对“有向无环图”,是一种枚举点的顺序算法,要求当处理某个点时,其所有的入点都已经处理过了(例如上面要处理2,保证4和6都已经处理过了)
2.拓扑排序要求起始点是入度为0的点,如上图的1或7
3.拓扑排序的顺序不固定,有多种可能性
4.利用入度数组ind和队列(queue)实现
代码:
//计算入度数组
while(m--){int u,v;cin>>u>>v;//u->vg[u].emplace_back(v);//更新indind[v]++;
}
//拓扑排序
void topo(){//队列queue<int> q;//入度为0的点先入队列for(int i=1;i<=n;i++){if(!ind[i]){q.emplace(i);}}//处理队列元素while(!q.empty()){int x=q.front();q.pop();//遍历儿子for(const auto &y:g[x]){//x->y,y入度减1ind[y]--;//y入度为0,说明y的入度点全处理过了,y才能放入队列if(!ind[y]) q.emplace(y);}}
}
/*
输入:
7 8
1 4
1 6
4 2
6 2
2 3
6 3
7 3
2 5队列顺序:1 7 4 6 2 3 5
*/
拓扑排序+动态规划
1.当从x->y时,有状态转移dp[x]->dp[y]
代码:
//拓扑排序
void topo(){//队列queue<int> q;//入度为0的点先入队列for(int i=1;i<=n;i++){if(!ind[i]){q.emplace(i);}}//处理队列元素while(!q.empty()){int x=q.front();q.pop();//遍历儿子for(const auto &y:g[x]){//x->y,y入度减1ind[y]--;//动态规划,dp[x]->dp[y]dp[y]=f(dp[x])//y入度为0,说明y的入度点全处理过了,y才能放入队列if(!ind[y]) q.emplace(y);}}
}
1337走多远
学习:
1.经典拓扑排序加动态规划,dp数组表示入度为0的点到当前点的最大距离,因为一个y可能有多个x到达,所以有状态转移方程dp[y]=max(dp[y],dp[x]+1)
,最终答案ans就等于dp数组中的最大值
代码:
#include <bits/stdc++.h>using namespace std;
const int N=1e6+10;
typedef long long ll;
int n,m,ind[N]; //ind[i]为第i个点的入度
ll dp[N],ans;//dp[i]为入度为0的点到第i个点的最大距离
vector<int> g[N]; void topo(){queue<int> q;//入度为0的点入队列for(int i=1;i<=n;i++){if(!ind[i]){q.emplace(i);}} //遍历队列while(!q.empty()){int x=q.front();q.pop();//遍历儿子for(const auto &y:g[x]){//ind[y]--ind[y]--;//更新dp[y]dp[y]=max(dp[y],dp[x]+1);//y入度为0则入队列if(!ind[y]) q.emplace(y); } }
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;while(m--){int u,v;cin>>u>>v;g[u].emplace_back(v);ind[v]++;}bool flag=false;//入度为0的点都不存在儿子则输出0for(int i=1;i<=n;i++){if(ind[i]==0 && g[i].size()!=0){flag=true;}} if(!flag){cout<<0;return 0;}topo();//获得答案for(int i=1;i<=n;i++){if(dp[i]>ans) ans=dp[i];} cout<<ans;return 0;
}
3351最小字典序排列
学习:
1.此题要求即拓扑排序的要求,但是难点在于拓扑排序的结果有很多种可能,答案要最小字典序排序,已知拓扑排序能实现在队列中的元素肯定是入度为0了,只要保证每次取出来的最小即可,将队列更换为优先级队列,每次取出来的元素放入ans数组,最终根据ans数组答案输出结果即可
代码:
#include <bits/stdc++.h>using namespace std;
const int N=2e5+10;
typedef long long ll;
int n,m,ind[N]; //ind[i]为第i个点的入度
vector<int> g[N];
vector<int> ans; void topo(){//优先级队列,保证出的元素是当前队列中最小的priority_queue<int,vector<int>,greater<int>> q;//入度为0的点入队列for(int i=1;i<=n;i++){if(!ind[i]){q.emplace(i);}} //遍历队列while(!q.empty()){int x=q.top();q.pop();ans.emplace_back(x);//遍历儿子for(const auto &y:g[x]){//ind[y]--ind[y]--;//y入度为0则入队列if(!ind[y]) q.emplace(y); } }
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;while(m--){int u,v;cin>>u>>v;g[u].emplace_back(v);ind[v]++;}topo();if(ans.size()<n) cout<<-1;else{for(const auto &x:ans) cout<<x<<" ";}return 0;
}
最短路径问题
1.Floyd算法:多源最短路问题,无负权,n<=500,稠密图,O(n^3),无向图
2.Dijkstra算法::单源最短路问题,*无负权,稀疏图,O(nlogm),堆优化,有向图(邻接表就存一个)
Floyd算法
学习:
1.本质是动态规划,用来解决多源最短路问题,即可以求得任意dp[i][j](从i到j)
的距离
2.通过枚举中间点k,实现状态转移
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]
3.枚举顺序:中间点必须最先枚举,否则先枚举i和j,再枚举k,如果i到j的最短路要经过多个中间点,会发生错误,而先枚举中间点,是一小段一小段更新的
4.要求边权不能为负数
5.算法复杂的O(n^3),所以只能解决n<=500的问题(优先判断)
6.注意dp的初始化:
const ll inf=1e18
//尽量不用memset处理除了0和-1以外的其他值
for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j]=inf;}
}
//每个点到自己距离为0
for(int i=1;i<=n;i++) dp[i][i]=0;
//放止多重边
dp[u][v]=min(dp[u][v],w);
dp[v][u]=min(dp[v][u],w);
代码:
//先枚举中间点k
for(int k=1;k<=n;k++){//再枚举i和jfor(int i=1;i<=n;i++){for(int j=1;j<=n;j++){//状态转移dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);}}
}
1121蓝桥公园
学习:
1.最大值inf开const ll inf=1e18
(int最大开到1e9,long long最大开到1e18)
2.除了0和-1,其他赋值不要用memset,全遍历赋值
for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j]=inf;}
}
3.每个点到自己距离初始化为0
for(int i=1;i<=n;i++) dp[i][i]=0;
4.放置输入多重边
dp[u][v]=min(dp[u][v],w);
dp[v][u]=min(dp[v][u],w);
代码:
#include <bits/stdc++.h>using namespace std;
typedef long long ll;
typedef pair<int,ll> PIII;
const int N=410;
const ll Inf=1e18;
ll dp[N][N]; //最短路径
int n,m,q;int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m>>q;//尽量不用memset处理除了0和-1以外的其他值for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j]=Inf;}} //每个点到自己距离为0for(int i=1;i<=n;i++) dp[i][i]=0;for(int i=1;i<=m;i++){int u,v;ll w;cin>>u>>v>>w;//放止多重边 dp[u][v]=min(dp[u][v],w);dp[v][u]=min(dp[v][u],w);} //floyd更新dpfor(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);}}} while(q--){int st,ed;cin>>st>>ed;if(dp[st][ed]==Inf) cout<<-1<<endl;else cout<<dp[st][ed]<<endl;}return 0;
}
Dijkstra算法
![[dijkstra算法.png]]
学习:
1.高效处理非负权边的单源最短路问题
2.按照Dijkstra算法的贪心思想,第一次走到的时候距离一定是最短距离,所以一个点不可能走第二次
2.堆优化版本,使用优先队列priority_queue实现
3.预备代码
代码:
ll d[N]; //i到源点的距离,初始化为Inf
bitset<N> vis;//表示某个点是否走过,按照Dijkstra算法的贪心思想,第一次走到的时候距离一定是最短距离,所以一个点不可能走第二次
struct Node{//x为点编号,w表示源点到x的最短距离int x;ll w; //初始化Node(int tx,ll tw):x(tx),w(tw){}//重载<号bool operator< (const Node &u)const{//先按w降序,优先队列中w最小的作为堆顶if(w!=u.w) return w>u.w; //u.w>w也行//再按x升序,优先队列中x大的作为堆顶(这个排序无所谓)return x>u.x;}
};priority_queue<Node> pq;
4.Dijkstra算法代码
代码:
//输入源点
void dijk(int st){d[st]=0;pq.emplace(st,d[st]);//遍历队列while(!pq.empty()){Node t=pq.top();pq.pop();//每个结点只遍历一次if(vis[t.x]) continue;//标记为走过vis[t.x]=true;//遍历儿子for(const auto &y:g[t.x]){//关键一步,x->y.first,若从x加上y.second到y.first小于原来的d[y.first],则更新if(d[t.x]+y.second<d[y.first]){//更新d[y.first]d[y.first]=d[t.x]+y.second;//放入队列pq.emplace(y.first,d[y.first]);}}}
}
1122蓝桥王国
学习:
1.还是要注意int和ll之间的转换
代码:
#include <bits/stdc++.h>using namespace std;
typedef long long ll;
typedef pair<int,ll> PII;
const int N=3e5+10;
const ll Inf=2e18;
int n,m;
vector<PII> g[N]; //邻接表存图
ll dist[N]; //st到i的最短距离
struct Node{//x为结点编号,w为x到st的最短距离 int x;ll w;Node(int tx,ll tw):x(tx),w(tw){}bool operator< (const Node &u)const{//w降序排,优先队列先取最短的距离 if(w!=u.w) return w>u.w;//x降序排,优先队列先取最小的 return x>u.x;}
};
//优先队列
priority_queue<Node> pq;
bitset<N> vis;//dijstra算法
void dijkstra(int st){dist[st]=0;pq.emplace(st,dist[st]);//遍历优先队列while(!pq.empty()){Node t=pq.top();pq.pop();//遍历过来跳过if(vis[t.x]) continue;//更新vis vis[t.x]=true;//遍历儿子for(const auto &y:g[t.x]){//x经过y.second距离到达y.first,比之间的最短距离短,则更新if(dist[t.x]+y.second<dist[y.first]){dist[y.first]=dist[t.x]+y.second;//放入y,拓展 pq.emplace(y.first,dist[y.first]); } } }
} int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;//初始化距离for(int i=1;i<=n;i++) dist[i]=Inf;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;g[u].emplace_back(v,w);}dijkstra(1);for(int i=1;i<=n;i++){if(dist[i]==Inf) cout<<-1<<" ";else cout<<dist[i]<<" ";}return 0;
}
Johnson算法(待看)
学习:
1.三步走:
(1)设置超级源点,用BellmanFord求单源最短路得到"势能"
(2)在势能的帮助下重新设置每条边的权重
(3)跑n次Dijkstra算法计算出所有点的单源最短路,即得到了全源最短路
生成树
1.最小生成树(MST)(无向图):
对于一个连通图,剔除其中一部分边,而保留一部分边,使得剩下的部分构成一颗树,此时共n个顶点,n-1条边,并且这棵树的所有边的权值之和最小(能够连接所有结点)
2.两种算法求解
Kruskal(O(mlogm))(遍历边)
Prim(O(mlogn))
3.最小生成树性质
(1)边权和是所有生成树中最小的
(2)最大边权是所有生成树中最小的
![[prim和kruskal区别.png]]
Kruskal(常用,一般都是稀疏图)
学习:
1.贪心思想,连接u和v权值最小的边
2.步骤
(1)将所有边按照边权升序排序(结构体数组+重新operator<)
(2)从小到大遍历边(u,v),如果(u,v)已经连通则跳过(压缩路径并查集判断),否则就连通(u,v)(并查集合并)
代码:
//结构体边
struct Edge{//顶点u,v,边权wint u,v;ll w;//初始化Edge(int tu,int tv,ll tw):u(tu),v(tv),w(tw){}//重新operator<bool operator<(const Edge &e)const{//按边权升序,数组前面元素是边权小的return w>e.w;}
};
//边数组
vector<Edge> es;
//父亲结点数组
int pre[N];
//路径压缩找根
int root(int x){//是根if(pre[x]==x) return x;pre[x]=root(pre[x]);return pre[x];
}
//kruskal算法
int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++) pre[i]=i;for(int i=1;i<=m;i++){int u,v,w;es.emplace_bakc(u,v,w);//不要更新pre[u]=v!!!,因为现在是存储边,下面遍历才连通u和v}//按边权排序sort(es.begin(),es.end());//按边权从小到大遍历(u,v)for(const auto &e:es){//已经连通则跳过(贪心保证之前的最小)if(root(e.u)==root(e.v)) continue;//没连通则连通,操作根结点pre[root(e.u)]=root(e.v);//更新答案ans=max(ans,e.w);}cout<<ans<<endl;
}
3322旅行销售员
学习:
1.因为推销员可以在城市加油,而在道路不能加油,所有答案ans油箱的最小容量就是最小生成树的最大一个边权值,ans=max(ans,e.c)
2.不要忘记struct里面初始化Edge(int tu,int tv,ll tw):u(tu),v(tv),w(tw){}
3.不要再输入存储边的时候更新pre,是在下面遍历边的时候才合并结点更新pre
代码:
#include <bits/stdc++.h>using namespace std;
const int N=1e5+10;
typedef long long ll;
int pre[N]; //记录父亲
//边
struct Edge{int u,v;ll w;//初始化Edge(int tu,int tv,ll tw):u(tu),v(tv),w(tw){} //按边权升序bool operator<(const Edge &e)const{return w<e.w;}
};
int t;
//找根
int root(int x){if(pre[x]==x) return x;pre[x]=root(pre[x]);return pre[x];
} int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>t;while(t--){int n,m;ll ans=0;cin>>n>>m;//边数组vector<Edge> es;//初始化prefor(int i=1;i<=n;i++) pre[i]=i;for(int i=1;i<=m;i++){int x,y;ll c;cin>>x>>y>>c;//x->yes.emplace_back(x,y,c);} //排序sort(es.begin(),es.end());//按边权从小到大遍历(u,v)for(const auto &e:es){//u,v已经连通if(root(e.u)==root(e.v)) continue;//未连通则合并 pre[root(e.u)]=root(e.v);//更新ansans=max(ans,e.w); } cout<<ans<<endl;}return 0;
}
Prim算法
学习:
1.维护一个mst集合,里面储存已经在最小生成树中的点
2.dist数组表示dist[x]:x到mst集合中所有点的最短距离
3.步骤:
(1)从起点(1)开始,每次找出不在mst集合中,dist最小的点x,将他放入mst中
(2)因为将x放入mst中,所以要更新非mst集合的点的dist(因为他们到x的距离可能小于他们到原不含x的mst集合中的点的距离)
dist[y]=min(dist[y],w)(w为x->y的距离)
(3)如果dist[y]
变小,则放入优先队列中
4.实现
mst集合用bitset来实现,等价于dijkstra里面的vis数组,判断一个点有没有访问过
5.与dijkstra算法区别:
(1)dist数组的含义
dijkstra:dist[i]表示源点到i的最短距离
Prim:dist[i]表示i到mst集合中的点的最短距离
(2)
dijkstra算法处理有向图,邻接表只存一个
而prim算法解决最小生成树,为无向图,邻接表要存两个
代码:
struct Edge{int x;//x为边的终点ll w;//w为x到集合的最短距离Edge(int tx,ll tw):x(tx),w(tw){}//因为用优先队列存储,每次拿出来最小的w,所以w降序排列bool operator<(const Edge &e)const{if(w!=e.w) return w>e.w;//按结点编号降序return x>e.x;}
};
vector<Edge> g[N];//邻接表,g[i]存储了从i出发的所有边
//都要存储
//g[u].emplace_back(v,w);
//g[v].emplace_back(u,w);//dist
ll dist[N];
int n,m;void prim(){//优先队列priority_queue<Edge> pq;//mst集合bitset<N> vis;//从1开始//在mst里面的元素到mst距离为0dist[1]=0;pq.emplace(1,dist[1]);ll ans=0;//最小生成树的最大边权//遍历队列while(!pq.empty()){Edge e=pq.top();pq.pop();if(vis[e.x]) continue;//将e.x放入mst集合vis[e.x]=true;res=max(res,dist[e.x]);//遍历儿子for(const auto &e2:g[e.x]){if(vis[e2.x]) continue;//更新此时不在mst集合里面的dist[e2.x]dist[e2.x]=min(dist[e2.x],e2.w);pq.emplace(e2.x,dist[e2.x]);}}
}
3322旅行销售员
#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int N=1e5+10;
const ll Inf=1e18;
int t;
//边
struct Edge{int x; //边终点x ll w;//初始化Edge(int tx,ll tw):x(tx),w(tw){} //按边权降序,优先队列 bool operator<(const Edge &e)const{if(w!=e.w) return w>e.w;return x>e.x;}
};
ll dist[N];
vector<Edge> g[N];ll prim(){ll ans=0;priority_queue<Edge> pq;bitset<N> vis;//从1开始dist[1]=0;pq.emplace(1,dist[1]);while(!pq.empty()){Edge e=pq.top();pq.pop();if(vis[e.x]) continue;//e.x进入集合 vis[e.x]=true;ans=max(e.w,ans);for(const auto &e2:g[e.x]){if(vis[e2.x]) continue;//e.x->e2.x//更新dist[e2.x]dist[e2.x]=min(dist[e2.x],e2.w);pq.emplace(e2.x,dist[e2.x]); }} return ans;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>t;while(t--){int n,m;cin>>n>>m;//dist初始化 for(int i=1;i<=n;i++) dist[i]=Inf;//g清空for(int i=1;i<=n;i++){g[i].clear();}for(int i=1;i<=m;i++){int x,y;ll c;cin>>x>>y>>c;//无向图 g[x].emplace_back(y,c);g[y].emplace_back(x,c);} cout<<prim()<<endl;}return 0;
}
相关文章:
蓝桥杯备赛 Day 21 图论基础
图的基础 ![[图的基础.png]] 1.图的存储方式 (1)邻接表(常用) vector<pair<int,int>> g[N]; //g[x]存放x的所有出点信息,二维数组 g[i][j]{first,second},first是从i出发的第j个出点,second表示边权 例如上图: g[1]{{2,0}.{3,0}} g[6]{{3,7}} g[4]{{5,0},{6,0}…...
MySQL数据库应用技术试卷
建一个以自己名字拼音为命名的数据库。(3分) CREATE DATABASE example; 令这个数据库为当前所使用的数据库。(2分) USE example; 写出如下student表结构语句。(95分) 表1: 列名 数据类型 …...
openssl源码分析之加密模式(modes)
openssl实现分组加密模式(例如AES128-CBC的CBC部分)的模块名字叫做modes,源代码位于 https://gitee.com/gh_mirrors/openssl/tree/master/crypto/modes 博主又打不开github了TT,只能找个gitee镜像 头文件是modes.h。 该模块目前…...
【Unity】Unity Transform缩放控制教程:实现3D模型缩放交互,支持按钮/鼠标/手势操作
【Unity 】Transform缩放控制教程:实现3D模型缩放交互,支持按钮/鼠标/手势操作 在Unity开发中,Transform组件承担着场景中物体的空间信息控制,包括位置、旋转和缩放。而缩放(Scale)操作,作为三…...
集成nacos2.2.1出现的错误汇总
总结 1.jdk问题 jdk要一致 2.idea使用问题 idea启动nacos要配置,idea启动类要启动两次,并配置两次vm参数 3.项目依赖问题 依赖要正确添加,有的模块就是不能用公共模块的pom配置,需要独立配置,先后启动顺序也要注意…...
从零到有的游戏开发(visual studio 2022 + easyx.h)
引言 本文章适用于C语言初学者掌握基本的游戏开发, 我将用详细的步骤引领大家如何开发属于自己的游戏。 作者温馨提示:不要认为开发游戏很难,一些基本的游戏逻辑其实很简单, 关于游戏的开发环境也不用担心,我会详细…...
海外高防服务器延迟优化——跨国业务安全加速的底层逻辑
本文深度解析海外高防服务器延迟优化的技术实现路径,揭示跨国业务场景下DDoS防护与网络性能的平衡法则。从物理线路选择到协议栈调优,从流量调度算法到安全检测机制重构,系统阐述降低20ms-50ms延迟的工程实践方案,并附2023年东南亚…...
常用环境部署(二十六)——Centos搭建MQTT服务端EMQX
1、安装docker https://blog.csdn.net/wd520521/article/details/112609796?spm1011.2415.3001.5331 2、安装EMQX4.4.4 (1)使用docker pull指令安装emqx镜像 docker pull emqx/emqx:4.4.4 (2)查看镜像 docker images 3、启…...
ecovadis认证基本概述,ecovadis认证审核有效期
EcoVadis认证基本概述 1. 什么是EcoVadis认证? EcoVadis是全球领先的企业可持续发展(ESG)评级平台,专注于评估企业在**环境(E)、劳工与人权(S)、商业道德(L)…...
2.8.4 iOS覆盖率SDK开发
iOS系统的覆盖率SDK,通过搭建本地的pod仓库,直接在podfile中添加指定的下载地址,就可以实现对被测试的app注入覆盖率SDK。 2.8.4.1 开发iOS覆盖率获取Pod私有库 在网上查找了相应的开发方法后,决定开发自己的依赖库,开发方法及步骤如下: 1,开发新的包 (1)通过Xcode创…...
Redhat(6)-ansible-变量
变量 1.作用域 Global scope:命令行中设置。 Play scope:play中设置。 Host scope :inventory中定义、facts收集或任务中注册,在主机组和主机上设置。 1.全局变量 1.1cmd命令 #1.全局变量 #显示变量 echo %PATH1.2.ansible变量 全局变量 var变量不加…...
麦科信光隔离探头在碳化硅(SiC)MOSFET动态测试中的应用
碳化硅(SiC)MOSFET 是基于宽禁带半导体材料碳化硅(SiC)制造的金属氧化物半导体场效应晶体管,相较于传统硅(Si)MOSFET,具有更高的击穿电压、更低的导通电阻、更快的开关速度以及更优异…...
android audiorecord
这里写目录标题 初始化失败记录 AudioRecord 初始化及参数介绍基本初始化参数详解1. audioSource (音频源)2. sampleRateInHz (采样率)3. channelConfig (声道配置)4. audioFormat (音频格式)5. bufferSizeInBytes (缓冲区大小) 完整初始化示例使用注意事项 参考地址 初始化失败…...
有一个变量 在有些线程没有加锁 有些线程加锁了,那我在这些加锁的线程中能起到对应的作用吗
这是一个非常经典、但也很危险的问题。 🧨 简单结论: 如果一个变量在某些线程访问时没有加锁,即使其他线程对它加了锁,也: ❌ 不能保证线程安全! ❌ 加锁的部分不会“保护”未加锁的部分! &am…...
【人工智能】AI大模型开发数学基础指南
目录 学习内容**1. 线性代数****2. 概率与统计****3. 微积分****4. 优化理论****5. 信息论****6. 数值计算****7. 离散数学****8. 统计学进阶****如何学习?****总结** 如何学习**1. 明确学习目标****2. 分阶段学习计划****阶段 1:夯实基础****阶段 2&…...
直流减速电机控制实验:Simulink应用层开发(3)
文章目录 1 阶段目标2 单元测试方法3 单元测试过程3.1 按键指令识别测试3.2 电机状态转换测试4 代码生成5 总结1 阶段目标 本文是《直流减速电机控制实验》的第四部分,会通过图文结合的方式,手把手带读者操作Simulink工具进行直流减速电机的应用层开发。 本章主要将《直流减…...
隔行换色总结
功能效果展示: 第一种思路: 使用数组,将数组的内容渲染到页面上,序号也就是将数组的下标输出到第一个td上,将数组的内容输出到第二个td上,(使用拼接字符串) 具体操作: …...
【kind管理脚本-2】脚本使用说明文档 —— 便捷使用 kind 创建、删除、管理集群脚本
当然可以,以下是为你这份 Kind 管理脚本写的一份使用说明文档,可作为 README.md 或内部文档使用: 🚀 Kind 管理脚本说明文档 本脚本是一个便捷的工具,帮助你快速创建、管理和诊断基于 Kind (Kubernetes IN Docker) 的…...
Python星球日记 - 第13天:封装、继承与多态
🌟引言: 上一篇:Python星球日记 - 第12天:面向对象编程(OOP)基础 名人说:不要人夸颜色好,只留清气满乾坤(王冕《墨梅》) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、引言二、封装的概念与实现1. 公有属性与私有属性2. 使用getter和sett…...
基于AT89C52单片机的GSM上报智能家居报警温度烟雾防盗系统
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/90579530?spm1001.2014.3001.5503 功能介绍: 1、功能:具有温度、烟雾、入侵报警功能,采用LCD1602液晶显示屏实时显示温度值与…...
北重数控滑台厂家:机器人地轨究竟是如何运作的,又在哪些领域发光发热呢?
机器人地轨是指利用机器人技术在地面上移动或执行任务的轨道系统。这种系统通常包括导轨、传动装置、传感器和控制系统等组成部分。机器人地轨的运作原理是通过控制传动装置沿着导轨移动,同时利用传感器获取周围环境信息并通过控制系统进行实时调节。 机器人地轨在…...
2025最新系统 Git 教程(三)
2.3 Git 基础 - 查看提交历史 查看提交历史 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。 我们使用一个非常简单的 simplegit 项目作为示例。 运行下面的命令获取该项目&…...
显示器各类异常处理方法
显示器各类异常处理方法 导航 文章目录 显示器各类异常处理方法导航画面无显示/黑屏/无HDMI信号输入显示器闪烁显示器花屏显示画面模糊或扭曲显示器颜色异常显示器出现死点或亮点 画面无显示/黑屏/无HDMI信号输入 首先应该检查的是显示器电源(真的有人弄掉电源…...
Error 1062 (23000): Duplicate entry ‘‘ for key ‘id‘`
目录 Error 1062 (23000): Duplicate entry for key id1. **问题分析**2. **解决方法****步骤 1:检查 id 字段的值****步骤 2:检查表结构****步骤 3:检查现有数据****步骤 4:检查插入逻辑****步骤 5:修改表结构&#…...
谈谈模板方法模式,模板方法模式的应用场景是什么?
一、模式核心理解 模板方法模式是一种行为设计模式,通过定义算法骨架并允许子类重写特定步骤来实现代码复用。 如同建筑图纸规定房屋结构,具体装修由业主决定,该模式适用于固定流程中需要灵活扩展的场景。 // 基础请求处理…...
未来蓉城:科技与生态共舞的诗意栖居-成都
故事背景 故事发生在中国四川成都的2075年,展现科技与自然深度交融的未来城市图景。通过六个充满想象力的生态装置场景,描绘市民在智慧城市中诗意栖居的生活状态,展现环境保护与人文传承的和谐共生。 故事内容 在电子竹林轻轨站,通…...
模仿axios的封装效果来封装fetch,实现baseurl超时等
因为要在cocos游戏项目里面发送网络请求获取数据,并且还有可能用到websocket发送请求,所以这里封装一个fetch放便使用: // fetch封装// 基础配置 const BASE_URL 你的url const TIMEOUT 5000// 请求封装 const http async (url: string, …...
Linux(CentOS10) gcc编译
本例子摘自《鸟哥的linux私房菜-基础学习第四版》 21.3 用make进行宏编译 书中的代码在本机器(版本见下)编译出错,改正代码后发布此文章: #kernel version: rootlocalhost:~/testmake# uname -a Linux localhost 6.12.0-65.el10.x86_64 #1…...
Design Compiler:语法检查工具dcprocheck
相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 dcprocheck是一个在Design Compiler存在于安装目录下的程序(其实它是一个指向snps_shell的符号链接,但snps_shell可以根据启动命令名判…...
根据日期格式化的常见规则和标准
根据日期格式化的常见规则和标准,2025年1月9日17:00可以正常格式化。具体分析如下: 1. 日期合法性验证 日期2025年1月9日不存在逻辑错误(如2月30日等非法日期),且时间17:00(24小时制)符合规范…...
macOS Chrome - 打开开发者工具,设置 Local storage
文章目录 macOS Chrome - 打开开发者工具设置 Local storage macOS Chrome - 打开开发者工具 方式2:右键点击网页,选择 检查 设置 Local storage 选择要设置的 url,显示右侧面板 双击面板,输入要添加的内容 2025-04-08ÿ…...
idea 的 WEB-INF 下没有 classes 编译文件,如何添加?
idea 打开项目却没有在 WEB-INF 下找到 classes 编译文件 添加流程如下: 1、选中 File ->Project Structure 后右击 2、选中 Modules ->选中项目 ->点击 Paths ->修改 output path为:项目绝对路径\WebRoot\WEB-INF\classes 3、修改完成后&…...
EasyExcel结合多线程+控制sheet页全量导出
业务分析 内部平台需要一个导出mysql数据到excel的方法,所以使用了EasyExcel 因为EasyExcel的sheet页是放到一个List里面的,如果把百万量级的数据放到sheet页中全量写入会有OOM风险,所以最终选择的方案是分sheet页写入 同时因为该平台是多…...
【学习笔记】RL4LLM
字数溢出,分了一半出来 上半段:LLMRL 文章目录 8 [RL4LLM] 理解 reasoning model Tokenizer 的 chat template,vllm inferencetokenizerchat templatedistill tokenizerqwen tokenizer apply chat templatevllm inference 9 [RL4LLM] PPO wo…...
在Windows搭建gRPC C++开发环境
一、环境构建 1. CMake Download CMake 2. Git Git for Windows 3. gRPC源码 git clone --recurse-submodules -b v1.67.1 --depth 1 --shallow-submodules https://github.com/grpc/grpc grpc-1.67.1二、使用CMake生成工程文件 mkdir cmake_build cd cmake_build cmake…...
NO.76十六届蓝桥杯备战|数据结构-单调栈|发射站|Largest Rectangle in a Histogram(C++)
什么是单调栈? 单调栈,顾名思义,就是具有单调性的栈。它依旧是⼀个栈结构,只不过⾥⾯存储的数据是递增或者递减的。这种结构是很容易实现的(如下⾯的代码),但重点是维护⼀个单调栈的意义是什么 …...
消息队列(Message Queue)简介
消息队列是一种进程间通信(IPC)机制,允许不同进程通过发送和接收消息进行 异步通信。它的核心特点包括: 解耦:消息队列解耦了生产者和消费者,简化了系统设计。 持久化存储:支持将消息存储在队列…...
动/静态库
1.先了解一下动静态库 上图可以看出来静态库就是由一堆进过链接阶段的.o文件组成的.a文件。在这里必须要强调的是库文件格式一定是libxxx.a/so在你进行路径查找使用的时候要去掉lib和后缀使用! 静态库 概念:在程序编译链接阶段,其代码被完整…...
KWDB创作者计划—边缘计算:从概念到落地的技术解读
引言 随着物联网(IoT)和人工智能(AI)的快速发展,数据量呈爆炸式增长,传统的云计算架构逐渐暴露出延迟高、带宽占用大等问题。边缘计算作为一种新兴的分布式计算范式,正在改变数据处理的方式。本…...
ubuntu根文件系统通过uMTP-Responder实现usb的MTP功能
实现mtp设备 添加服务 /home/flynn/firfly_rootfs/lib/systemd/system/adbd.service #start [Unit] Description Adbd for linux Beforerockchip.service[Service] Typeforking ExecStart/etc/init.d/adbd.sh start ExecStop/etc/init.d/adbd.sh stop ExecReload/etc/init.d…...
8、nRF52xx蓝牙学习(boards.h文件学习)
boards.h文件的代码如下: #ifndef BOARDS_H #define BOARDS_H#include "nrf_gpio.h" #include "nordic_common.h"#if defined(BOARD_NRF6310)#include "nrf6310.h" #elif defined(BOARD_PCA10000)#include "pca10000.h" #…...
辛格迪客户案例 | 河南宏途食品实施电子合约系统(eSign)
01 河南宏途食品有限公司:食品行业的数字化践行者 河南宏途食品有限公司(以下简称“宏途食品”)作为国内食品行业的创新企业,专注于各类食品的研发、生产和销售。公司秉承“质量为先、创新驱动、服务至上”的核心价值观ÿ…...
webrtc-stats
1. RTP 相关统计 1.1 inbound-rtp (接收端统计) 接收到的 RTP 流统计信息,包含以下关键指标: bytesReceived: 接收到的字节总数packetsReceived: 接收到的数据包总数packetsLost: 丢失的数据包数量jitter: 数据包到达时间的抖动(毫秒&…...
【LangChain框架组成】 LangChain 技术栈的模块化架构解析
目录 整体架构概述 整体架构层级划分 模块详细解析 1. 部署与服务层(LangServe & Deployments) 2. 应用模板层(Templates & Committee Architectures) 3. 核心功能层(LangChain) 4. 社区扩展…...
RNN、LSTM、GRU汇总
RNN、LSTM、GRU汇总 0、论文汇总1.RNN论文2、LSTM论文3、GRU4、其他汇总 1、发展史2、配置和架构1.配置2.架构 3、基本结构1.神经元2.RNN1. **RNN和前馈网络区别:**2. 计算公式:3. **梯度消失:**4. **RNN类型**:(查看发展史)5. **…...
用TypeScript和got库编写爬虫程序指南
用TypeScript和got库写一个爬虫程序。首先,我得确认他们对TypeScript和Node.js的基础了解,可能他们已经有了一些JS的经验,但不确定。接下来,需要明确爬虫的目标,比如要爬取的网站、需要的数据类型以及处理方式。 首先…...
使用 Spring Boot 快速构建企业微信 JS-SDK 权限签名后端服务
使用 Spring Boot 快速构建企业微信 JS-SDK 权限签名后端服务 本篇文章将介绍如何使用 Spring Boot 快速构建一个用于支持企业微信 JS-SDK 权限校验的后端接口,并提供一个简单的 HTML 页面进行功能测试。适用于需要在企业微信网页端使用扫一扫、定位、录音等接口的…...
【软考-架构】13.2、软件层次风格
✨资料&文章更新✨ GitHub地址:https://github.com/tyronczt/system_architect 文章目录 2、层次架构风格两层C/S架构三层C/S架构三层B/S架构富互联网应用RIAMVC架构MVP架构MVVM架构 ✨3、面向服务的架构风格SOASOA中应用的关键技术WEB Service企业服务总线ESB …...
Java 进阶-全面解析
目录 异常处理 集合框架 List 集合 Set 集合 Map 集合 文件与字符集 IO 流 多线程 通过继承Thread类创建线程 通过实现Runnable接口创建线程 线程同步示例 线程通信示例 网络编程 Java 高级技术 反射机制 动态代理 注解 异常处理 在 Java …...
mongodb 创建keyfile
在 MongoDB 中,keyFile 是用于副本集成员间内部认证的密钥文件。它是一个包含随机字符串的文件,所有副本集成员必须使用相同的 keyFile 进行通信。以下是创建和配置 keyFile 的详细步骤。 创建 KeyFile 的步骤 1. 生成随机字符串 使用以下命令生成一个…...