经典基本算法模块
C程序经典算法50例

C程序经典算法50例1.二分查找算法:在有序数组中查找指定元素。
2.冒泡排序算法:通过不断比较相邻元素并交换位置,将较大的元素向后冒泡。
3.快速排序算法:通过选择一个基准元素,将数组分割为左右两部分,并递归地对两部分进行快速排序。
4.插入排序算法:将数组划分为已排序和未排序两部分,每次从未排序中选择一个元素插入到已排序的合适位置。
5.选择排序算法:遍历数组,每次选择最小元素并放置在已排序部分的末尾。
6.希尔排序算法:将数组按照一定间隔进行分组并分别进行插入排序,然后逐步减小间隔并重复这个过程。
7.归并排序算法:将数组递归地划分为两部分,然后将两个有序的部分进行合并。
8.桶排序算法:将元素根据特定的映射函数映射到不同的桶中,然后对每个桶分别进行排序。
9.计数排序算法:统计每个元素的出现次数,然后根据计数进行排序。
10.基数排序算法:从低位到高位依次对元素进行排序。
11.斐波那契数列算法:计算斐波那契数列的第n项。
12.阶乘算法:计算给定数字的阶乘。
13.排列问题算法:生成给定数组的全排列。
14.组合问题算法:生成给定数组的所有组合。
15.最大连续子序列和算法:找出给定数组中和最大的连续子序列。
16.最长递增子序列算法:找出给定数组中的最长递增子序列。
17.最长公共子序列算法:找出两个给定字符串的最长公共子序列。
18.最短路径算法:计算给定有向图的最短路径。
19.最小生成树算法:构建给定连通图的最小生成树。
20.汉诺塔算法:将n个圆盘从一个柱子移动到另一个柱子的问题。
21.BFS算法:广度优先算法,用于图的遍历和查找最短路径。
22.DFS算法:深度优先算法,用于图的遍历和查找连通分量。
23.KMP算法:字符串匹配算法,用于查找一个字符串是否在另一个字符串中出现。
24.贪心算法:每次都选择当前情况下最优的方案,适用于求解一些最优化问题。
25.动态规划算法:将一个大问题划分为多个子问题,并通过子问题的解求解整个问题,适用于求解一些最优化问题。
常用算法举例范文

常用算法举例范文在计算机科学中,算法是解决问题的一系列有序步骤,它能够帮助我们解决各种各样的问题。
以下是一些常用的算法及其举例:1.排序算法:-冒泡排序:通过比较相邻元素并交换位置来将最大的元素逐渐移动到数组的末尾。
-快速排序:选择一个基准元素,将数组分为两部分,左边的元素小于基准,右边的元素大于基准,然后递归地对两部分进行快速排序。
-归并排序:将数组划分为两个子数组,对每个子数组分别进行归并排序,然后将两个有序子数组合并成一个有序数组。
2.查找算法:-二分查找:对于有序数组,通过与中间元素进行比较,将查找范围缩小一半,直到找到目标元素或确定不存在。
-哈希查找:通过将关键字映射到数组的索引位置来进行查找,可以在常数时间内找到目标元素。
3.图算法:-广度优先(BFS):从起始节点开始,逐层遍历图中的节点,直到找到目标节点。
-深度优先(DFS):从起始节点开始,沿着一条路径一直向下,直到找到目标节点或无法继续为止。
4.动态规划算法:-背包问题:给定一组物品和一个容量限制,选择一些物品放入背包中,使得总价值最大。
-最长公共子序列(LCS):给定两个字符串,找到它们的最长公共子序列的长度。
5.数学算法:-欧几里得算法:计算两个整数的最大公约数。
-快速幂算法:计算一个数的幂运算,通过将指数进行二进制拆分来减少计算次数。
6.字符串处理算法:-KMP算法:通过利用已匹配字符的信息来避免不必要的回溯,实现高效的字符串匹配。
- Boyer-Moore算法:利用模式串中的信息来进行快速的字符串匹配。
7.图像处理算法:-图像平滑算法:通过对图像进行滤波处理,去除图像中的噪声,使其更加平滑。
-图像边缘检测算法:通过检测图像中的边缘信息,突出物体的轮廓。
8.机器学习算法:-K均值聚类算法:将数据集划分为K个簇,使得同一个簇内的数据点之间的距离最小化。
-支持向量机(SVM):将数据集映射到高维空间,并通过找到最优的超平面来实现分类。
计算机常用算法

计算机常用算法一、排序算法排序算法是计算机程序中最基本的算法之一,它用于将一组数据按照一定的顺序进行排列。
常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些算法的目标都是将数据从小到大或从大到小进行排序,以便于后续的处理和查找。
冒泡排序是一种简单的排序算法,它通过不断比较相邻元素的大小来将较大(或较小)的元素逐步交换到右侧(或左侧)。
选择排序则是依次选取未排序部分的最小(或最大)元素并放置到已排序部分的末尾。
插入排序则是将未排序部分的元素依次插入到已排序部分的合适位置。
快速排序是一种高效的排序算法,它通过选择一个基准元素,将数组划分为两个子数组,并对子数组进行递归排序。
归并排序则是将数组分成两个子数组,分别排序后再合并。
二、查找算法查找算法是用于在一组数据中寻找特定元素或满足特定条件的元素的算法。
常见的查找算法包括线性查找、二分查找、哈希查找等。
这些算法的目标都是在最短的时间内找到目标元素。
线性查找是最简单的查找算法,它依次遍历数据中的每个元素,直到找到目标元素或遍历完所有元素。
二分查找则是在有序数组中使用的一种查找算法,它通过不断缩小查找范围,将查找时间从O(n)降低到O(logn)。
哈希查找则是通过构建一个哈希表来实现的,将元素的关键字映射到对应的位置,以实现快速查找。
三、图算法图算法是解决图相关问题的算法,它在计算机科学中有着广泛的应用。
常见的图算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、最短路径算法(Dijkstra算法、Floyd-Warshall算法)、最小生成树算法(Prim算法、Kruskal算法)等。
深度优先搜索是一种遍历图的算法,它从一个起始节点开始,沿着一条路径一直遍历到最后一个节点,然后回溯到前一个节点,继续遍历其他路径。
广度优先搜索则是从起始节点开始,逐层遍历图中的节点,直到找到目标节点。
最短路径算法用于计算图中两个节点之间的最短路径,它可以解决最短路径问题,如求解地图上的最短路径。
五大常用算法资料课件

• 适用场景:Dijkstra算法适用于解决单源最短路径问题,例如在地图导航、物流配送等领域有广泛应用。 • 注意事项:在使用Dijkstra算法时,需要注意处理负权重的边,因为Dijkstra算法只能处理非负权重的问题。
THANKS
要点一
总结词
二分查找是一种在有序数组中查找特定元素的搜索算法, 它将数组分成两半,比较中间元素与目标值,如果中间元 素等于目标值则查找成功,如果目标值小于中间元素则在 前半部分数组中继续查找,如果目标值大于中间元素则在 后半部分数组中继续查找。
要点二
详细描述
二分查找的主要思想是将数组分成两半,比较中间元素与 目标值,如果中间元素等于目标值则查找成功,如果目标 值小于中间元素则在前半部分数组中继续查找,如果目标 值大于中间元素则在后半部分数组中继续查找。这个过程 递归进行,直到找到目标值或搜索区间为空。二分查找的 时间复杂度为O(logn),是一种高效的搜索算法。
Floyd-Warshall算法
01
02
03
04
Floyd-Warshall算法是一种 用于解决所有节点对之间最
短路径问题的图算法。
Floyd-Warshall算法的基本 思想是通过动态规划的方式 逐步计算出所有节点对之间 的最短路径。该算法的时间 复杂度为O(V^3),其中V是
节点数。
适用场景:Floyd-Warshall 算法适用于解决所有节点对 之间最短路径问题,例如在 社交网络分析、交通网络规
ACM常用算法模板

专用模板目录:一、图论1.最大团2.拓扑排序3.最短路和次短路4.SAP模板5.已知各点度,问能否组成一个简单图6.KRUSKAL7. Prim算法求最小生成树8. Dijkstra9 . Bellman-ford10. SPFA11. Kosaraju 模板12. tarjan 模板二、数学1. 剩余定理2. N!中质因子P的个数3.拓展欧几里得4.三角形的各中心到顶点的距离和5.三角形外接圆半径周长6.归并排序求逆序数7. 求N!的位数8.欧拉函数9. Miller-Rabin,大整数分解,求欧拉函数10. 第一类斯特林数11.计算表达式12.约瑟夫问题13.高斯消元法14. Baby-step,giant-step n是素数.n任意15. a^b%c=a ^(b%eular(c)+eular(c)) % c16.判断第二类斯特林数的奇偶性17.求组合数C(n,r)18.进制转换19.Ronberg算法计算积分20.行列式计算21. 返回x 的二进制表示中从低到高的第i位22.高精度运算 +-*/23.超级素数筛选三、数据结构1.树状数组2.线段树求区间的最大、小值3.线段树求区间和4.单调队列5.KMP模板6. 划分树,求区间第k小数7.最大堆,最小堆模板8. RMQ模板求区间最大、最小值9.快速排序,归并排序求逆序数.10.拓展KMP四、计算几何1.凸包面积2.Pick公式求三角形内部有多少点3.多边形边上内部各多少点以及面积pick4.平面最远点对5.判断矩形是否在矩形内6.判断点是否在多边形内7.判断4个点(三维)是否共面8.凸包周长9.等周定理变形一直两端点和周长求最大面积10.平面最近点对11.单位圆最多覆盖多少点(包括边上)12.多边形费马点求点到多边形各个点的最短距离13.矩形并周长14.zoj 2500 求两球体积并一、图论1.最大团#include<iostream>#include<algorithm>using namespace std;int n,m;int cn;//当前顶点数int best;//当前最大顶点数int vis[50];//当前解int bestn[50];//最优解int map[50][50];//临界表void dfs(int i){if(i>n){for(int j=1;j<=n;j++) bestn[j]=vis[j];best=cn;return ;}int ok=1;for(int j=1;j<i;j++){if(vis[j]==1&&map[i][j]==0){ok=0;break;}}if(ok){//进入左子树vis[i]=1;cn++;dfs(i+1);cn--;}if(cn+n-i>best){//进入右子树vis[i]=0;dfs(i+1);}}int main(){while(scanf("%d%d",&n,&m)==2){memset(vis,0,sizeof(vis));memset(map,0,sizeof(map));while(m--){int p,q;scanf("%d%d",&p,&q);map[p][q]=map[q][p]=1;//无向图}cn=0;best=0;dfs(1);printf("%d\n",best);}return 0;}2.拓扑排序#include<iostream>#include<cstring>using namespace std;int map[105][105],in[105],vis[105],ans[105],n;int flag;void dfs(int step){if(flag) return ;if(step==n+1) {flag=1; printf("%d",ans[1]);for(int i=2;i<=n;i++) printf(" %d",ans[i]);printf("\n");return ;}for(int i=1;i<=n;i++){if(vis[i]==0&&in[i]==0){vis[i]=1;for(int j=1;j<=n;j++){if(map[i][j]>0){map[i][j]=-map[i][j];in[j]--;}}ans[step]=i;dfs(step+1);vis[i]=0;for(int j=1;j<=n;j++){if(map[i][j]<0){map[i][j]=-map[i][j];in[j]++;}}}}}int main(){while(scanf("%d",&n)==1){flag=0;memset(map,0,sizeof(map));memset(vis,0,sizeof(vis));memset(in,0,sizeof(in));for(int i=1;i<=n;i++){int t;while(scanf("%d",&t),t){map[i][t]=1;in[t]++;}}dfs(1);}return 0;}3.最短路和次短路#include<iostream>#include<cstdio>#include<vector>#include<cstring>using namespace std;class Node{public:int e,w;//表示终点和边权};const int inf=(1<<25);int main(){int ci;cin>>ci;while(ci--){vector<Node> G[1005];//用邻接表存边int n,m;cin>>n>>m;for(int i=1;i<=m;i++){Node q;int u;cin>>u>>q.e>>q.w;G[u].push_back(q);}int s,f;//起点和终点cin>>s>>f;//dijkstra 求最短路和次短路int flag[1005][2];int dis[1005][2],cnt[1005][2];//0表示最短路,1表示次短路memset(flag,0,sizeof(flag));for(int i=1;i<=n;i++) dis[i][0]=dis[i][1]=inf;dis[s][0]=0;cnt[s][0]=1;//初始化for(int c=0;c<2*n;c++) //找最短路和次短路,故要进行2*n次循环也可以改成while(1){int temp=inf,u=-1,k;//找s-S'集合中的最短路径,u记录点的序号,k记录是最短路或者是次短路for(int j=1;j<=n;j++){if(flag[j][0]==0&&temp>dis[j][0]) temp=dis[j][0],u=j,k=0;else if(flag[j][1]==0&&temp>dis[j][1]) temp=dis[j][1],u=j,k=1;}if(temp==inf) break;//S'集合为空或者不联通,算法结束//更新路径flag[u][k]=1;for(int l=0;l<G[u].size();l++){int d=dis[u][k]+G[u][l].w,j=G[u][l].e;//important//4种情况if(d<dis[j][0]){dis[j][1]=dis[j][0];cnt[j][1]=cnt[j][0];dis[j][0]=d;cnt[j][0]=cnt[u][k];}else if(d==dis[j][0]){cnt[j][0]+=cnt[u][k];}else if(d<dis[j][1]){dis[j][1]=d;cnt[j][1]=cnt[u][k];}else if(d==dis[j][1]){cnt[j][1]+=cnt[u][k];}}}int num=cnt[f][0];//最短路int cc=cnt[f][1];//次短路}return 0;}4.SAP模板#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int inf=(1<<31)-1;const int point_num=300;int cap[point_num][point_num],dist[point_num],gap[point_num];//初始化见main里面int s0,t0,n;//源,汇和点数int find_path(int p,int limit=0x3f3f3f3f){if(p==t0) return limit;for(int i=0;i<n;i++)if(dist[p]==dist[i]+1 && cap[p][i]>0){int t=find_path(i,min(cap[p][i],limit));if(t<0) return t;if(t>0){cap[p][i]-=t;cap[i][p]+=t;return t;}}int label=n;for(int i=0;i<n;i++) if(cap[p][i]>0) label=min(label,dist[i]+1);if(--gap[dist[p]]==0 || dist[s0]>=n ) return -1;++gap[dist[p]=label];return 0;}int sap(){//初始化s,ts0=0,t0=n-1;int t=0,maxflow=0;gap[0]=n;while((t=find_path(s0))>=0) maxflow+=t;return maxflow;}int main(){int ci;while(cin>>ci>>n){//初始化memset(cap,0,sizeof(cap));memset(dist,0,sizeof(dist));memset(gap,0,sizeof(gap));//初始化capwhile(ci--){int x,y,c;cin>>x>>y>>c;x--;y--;cap[x][y]+=c;//因题而异}int ans=sap();cout<<ans<<endl;}return 0;}5.已知各点度,问能否组成一个简单图#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int inf=(1<<30);int d[1100];bool cmp(int x,int y){return x>y;}int main(){int ci;scanf("%d",&ci);while(ci--){int n,flag=1,cnt=0;scanf("%d",&n); for(int i=0;i<n;i++){scanf("%d",&d[i]);if(d[i]>n-1||d[i]<=0) flag=0; cnt+=d[i];}if(flag==0||cnt%2){printf("no\n");continue;}sort(d,d+n,cmp);for(int l=n;l>0;l--){for(int i=1;i<l&&d[0];i++){d[0]--,d[i]--;if(d[i]<0){flag=0;break;}}if(d[0]) flag=0;if(flag==0) break;d[0]=-inf;sort(d,d+l,cmp);}if(flag) printf("yes\n");else printf("no\n");}return 0;}6.KRUSKAL#include<iostream>#include<algorithm>using namespace std;int u[15005],v[15005],w[15005],fath[15005],r[15005];int ans1[15005],ans2[15005];bool cmp(int i,int j){return w[i]<w[j];}int find(int x){return fath[x]==x?x:fath[x]=find(fath[x]);}int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++) fath[i]=i;for(int i=1;i<=m;i++) r[i]=i;for(int i=1;i<=m;i++){cin>>u[i]>>v[i]>>w[i];}sort(r+1,r+m+1,cmp);int maxn=0,ans=0,k=0;for(int i=1;i<=m;i++){int e=r[i];int x=find(u[e]),y=find(v[e]);if(x!=y){ans+=w[e];fath[x]=y;if(w[e]>maxn) maxn=w[e];ans1[k]=u[e];ans2[k++]=v[e];}}return 0;}7.prime求最小生成树语法:prim(Graph G,int vcount,int father[]);参数:G:图,用邻接矩阵表示vcount:表示图的顶点个数father[]:用来记录每个节点的父节点返回值:null注意:常数max_vertexes 为图最大节点数常数infinity为无穷大源程序:#define infinity 1000000#define max_vertexes 5typedef int Graph[max_vertexes][max_vertexes];void prim(Graph G,int vcount,int father[]){int i,j,k;intlowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes]; for (i=0;i<vcount;i++){lowcost[i]=G[0][i];closeset[i]=0;used[i]=0;father[i]=-1;}used[0]=1;for (i=1;i<vcount;i++){j=0;while (used[j]) j++;for (k=0;k<vcount;k++)if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;father[j]=closeset[j];used[j]=1;for (k=0;k<vcount;k++)if (!used[k]&&(G[j][k]<lowcost[k])){ lowcost[k]=G[j][k];closeset[k]=j; }}}8.Dijkstra语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]); 参数:G:图,用邻接矩阵表示n:图的顶点个数s:开始节点t:目标节点path[]:用于返回由开始节点到目标节点的路径返回值:最短路径长度注意:输入的图的权必须非负顶点标号从0 开始用如下方法打印路径:i=t;while (i!=s){printf("%d<--",i+1);i=path[i];}printf("%d\n",s+1);源程序:int Dijkstra(Graph G,int n,int s,int t, int path[]){int i,j,w,minc,d[max_vertexes],mark[max_vertexes];for (i=0;i<n;i++) mark[i]=0;for (i=0;i<n;i++){ d[i]=G[s][i];path[i]=s; }mark[s]=1;path[s]=0;d[s]=0;for (i=1;i<n;i++){minc=infinity;w=0;for (j=0;j<n;j++)if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}mark[w]=1;for (j=0;j<n;j++)if((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j])){ d[j]=d[w]+G[w][j];path[j]=w; }}return d[t];}9.Bellman-ford语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);参数:G:图,用邻接矩阵表示n:图的顶点个数s:开始节点t:目标节点path[]:用于返回由开始节点到目标节点的路径success:函数是否执行成功返回值:最短路径长度注意:输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0顶点标号从0 开始用如下方法打印路径:i=t;while (i!=s){printf("%d<--",i+1);i=path[i];}printf("%d\n",s+1);源程序:int Bellman_ford(Graph G,int n,int s,int t,int path[],int success){int i,j,k,d[max_vertexes];for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}d[s]=0;for (k=1;k<n;k++)for (i=0;i<n;i++)for (j=0;j<n;j++)if (d[j]>d[i]+G[i][j]){d[j]=d[i]+G[i][j];path[j]=i;}success=0;for (i=0;i<n;i++)for (j=0;j<n;j++)if (d[j]>d[i]+G[i][j]) return 0;success=1;return d[t];}10. SPFA#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;const __int64 maxn=1001000;const __int64 inf=1000100000;struct edge//邻接表{__int64 t,w;//s->t=w;__int64 next;//数组模拟指针};__int64 p[maxn],pf[maxn];//邻接表头节点edge G[maxn],Gf[maxn];//邻接表__int64 V,E;//点数[1-n] 边数__int64 dis[maxn];__int64 que[maxn],fro,rear;//模拟队列__int64 vis[maxn];__int64 inque[maxn];//入队次数bool spfa(__int64 s0){fro=rear=0;for(__int64 i=1;i<=V;i++) dis[i]=inf;dis[s0]=0;memset(vis,0,sizeof(vis));memset(inque,0,sizeof(inque));que[rear++]=s0;vis[s0]=1;inque[s0]++;while(fro!=rear){__int64 u=que[fro];fro++;if(fro==maxn) fro=0;vis[u]=0;for(__int64 i=p[u];i!=-1;i=G[i].next){__int64 s=u,t=G[i].t,w=G[i].w;if(dis[t]>dis[s]+w){dis[t]=dis[s]+w;if(vis[t]==0){que[rear++]=t,vis[t]=1;inque[t]++;if(inque[t]>V) return false;if(rear==maxn) rear=0;}}}}return true;}int main(){__int64 ci;scanf("%I64d",&ci);while(ci--){scanf("%I64d%I64d",&V,&E);memset(p,-1,sizeof(p));memset(pf,-1,sizeof(pf)); for(__int64 i=0;i<E;i++){__int64 u,v,w;scanf("%I64d%I64d%I64d",&u,&v,&w);G[i].t=v;G[i].w=w;G[i].next=p[u];p[u]=i;Gf[i].t=u;Gf[i].w=w;Gf[i].next=pf[v];pf[v]=i;}__int64 ans=0;spfa(1);//求第一个点到其他点的最短距离和for(__int64 i=1;i<=V;i++) ans+=dis[i];//反方向再来一次spfa 求其他点到第一个点的最短距离和 for(__int64 i=1;i<=V;i++) p[i]=pf[i];for(__int64 i=0;i<E;i++) G[i]=Gf[i];spfa(1);for(__int64 i=1;i<=V;i++) ans+=dis[i];printf("%I64d\n",ans);}return 0;}11.Kosaraju模板#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;struct edge{int t,w;//u->t=w;int next;};int V,E;//点数(从1开始),边数int p[maxn],pf[maxn];//邻接表原图,逆图edge G[maxn],Gf[maxn];//邻接表原图,逆图int l,lf;void init(){memset(p,-1,sizeof(p));memset(pf,-1,sizeof(pf));l=lf=0;}void addedge(int u,int t,int w,int l){G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}void addedgef(int u,int t,int w,int lf){Gf[l].w=w;Gf[l].t=t;Gf[l].next=pf[u];pf[u]=l;}///Kosaraju算法,返回为强连通分量个数bool flag[maxn]; //访问标志数组int belg[maxn]; //存储强连通分量,其中belg[i]表示顶点i属于第belg[i]个强连通分量int numb[maxn]; //结束时间(出栈顺序)标记,其中numb[i]表示离开时间为i的顶点//用于第一次深搜,求得numb[1..n]的值void VisitOne(int cur, int &sig){flag[cur] = true;for (int i=p[cur];i!=-1;i=G[i].next){if (!flag[G[i].t]){VisitOne(G[i].t,sig);}}numb[++sig] = cur;}//用于第二次深搜,求得belg[1..n]的值void VisitTwo(int cur, int sig){flag[cur] = true;belg[cur] = sig;for (int i=pf[cur];i!=-1;i=Gf[i].next){if (!flag[Gf[i].t]){VisitTwo(Gf[i].t,sig);}}//Kosaraju算法,返回为强连通分量个数int Kosaraju_StronglyConnectedComponent(){int i, sig;//第一次深搜memset(flag,0,sizeof(flag));for ( sig=0,i=1; i<=V; ++i ){if ( false==flag[i] ){VisitOne(i,sig);}}//第二次深搜memset(flag,0,sizeof(flag));for ( sig=0,i=V; i>0; --i ){if ( false==flag[numb[i]] ){VisitTwo(numb[i],++sig);}}return sig;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int u=i,t,w=1;while(scanf("%d",&t)==1&&t){E++;addedge(u,t,w,l++);addedgef(t,u,w,lf++);}}int ans=Kosaraju_StronglyConnectedComponent(); printf("%d\n",ans);}return 0;12.tarjan模板//自己模板#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;int V,E;//点数(1) 边数struct edge//邻接表{int t,w;//u->t=w;int next;};int p[maxn];//表头节点edge G[maxn];int l;void init(){memset(p,-1,sizeof(p));l=0;}//添加边void addedge(int u,int t,int w,int l)//u->t=w;{G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}//tarjan算法求有向图强联通分量int dfn[maxn],lowc[maxn];//dfn[u]节点u搜索的次序编号,lowc[u]u或者u的子树能够追溯到的栈中的最早的节点int belg[maxn];//第i个节点属于belg[i]个强连通分量int stck[maxn],stop;//stck栈int instck[maxn];//第i个节点是否在栈中int scnt;//强联通分量int index;void dfs(int i){dfn[i]=lowc[i]=++index;instck[i]=1;//节点i入栈stck[++stop]=i;for(int j=p[i];j!=-1;j=G[j].next){int t=G[j].t;//更新lowc数组if(!dfn[t])//t没有遍历过{dfs(t);if(lowc[i]>lowc[t]) lowc[i]=lowc[t];}//t是i的祖先节点else if(instck[t]&&lowc[i]>dfn[t]) lowc[i]=dfn[t];}//是强连通分量的根节点if(dfn[i]==lowc[i]){scnt++;int t;do{t=stck[stop--];instck[t]=0;belg[t]=scnt;}while(t!=i);}}int tarjan(){stop=scnt=index=0;memset(dfn,0,sizeof(dfn));memset(instck,0,sizeof(instck));for(int i=1;i<=V;i++){if(!dfn[i]) dfs(i);}return scnt;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int x;while(scanf("%d",&x)==1&&x){E++;addedge(i,x,1,l++);}}int ans=tarjan();printf("%d\n",ans);}return 0;}//吉大模板邻接表版#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;int V,E;//点数(1) 边数struct edge//邻接表{int t,w;//u->t=w;int next;};int p[maxn];//表头节点edge G[maxn];int l;void init(){memset(p,-1,sizeof(p));l=0;}//添加边void addedge(int u,int t,int w,int l)//u->t=w;{G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}//tarjan算法求有向图强联通分量int dfn[maxn],lowc[maxn];//dfn[u]节点u搜索的次序编号,lowc[u]u或者u的子树能够追溯到的栈中的最早的节点int stck[maxn],stop;//stck栈int pre[maxn];//int scnt;//强联通分量int cnt;//void dfs(int v)//1-V{int t,minc=lowc[v]=pre[v]=cnt++;stck[stop++]=v;for(int i=p[v];i!=-1;i=G[i].next){int pv=G[i].t;if(pre[pv]==-1) dfs(pv);if(lowc[pv]<minc) minc=lowc[pv]; }if(minc<lowc[v]){lowc[v]=minc;return ;}do{dfn[t=stck[--stop]]=scnt;lowc[t]=V;}while(t!=v);++scnt;}int tarjan(){stop=cnt=scnt=0;memset(pre,-1,sizeof(pre));for(int i=1;i<=V;i++){if(pre[i]==-1) dfs(i);}return scnt;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int x;while(scanf("%d",&x)==1&&x){E++;addedge(i,x,1,l++);}}int ans=tarjan();printf("%d\n",ans);}return 0;}二、数学1.剩余定理int mod(int c[],int b[],int n){int all_multy=1,sum=0;int i,j,x[5];for(i=0;i<n;i++)all_multy*=c[i];for(i=0;i<n;i++)x[i]=all_multy/c[i];for(i=0;i<n;i++){j=1;while((x[i]*j)%c[i]!=1)j++;x[i]*=j;}for(i=0;i<n;i++)sum+=(b[i]*x[i]);return sum%all_multy;}2.N!中质因子P的个数//对于任意质数p,n!中有(n/p+n/p^2+n/p^3+...)个质因子p。
常用算法模型

常用算法模型
常用的数学模型:初等模型,线性代数模型,概率统计模型,图论模型,规划模型,微分方程模型,回归模型,离散模型,模糊数学模型,灰色理论模型等。
常用的算法:1.蒙特卡罗算法;2.数据拟合、参数估计、插值等数据处理算法;3.线性规划、整数规划、多元规划、二次规划等规划类算法;4.图论算法;5.动态规划、回溯搜索、分治算法、分支定界等计算机算法;6.最优化理论的三大非经典算法:模拟退火法、神经网络算法、遗传算法;7.网格算法和穷举法;8.连续数据离散化方法;
9.数值分析算法;10.图像处理算法。
常用的软件:学习数学建模,常用的软件有:matlab、lingo、lindo、Mathematica、Maple、Spass和SAS等。
其中Lingo,Lindo 软件常用于非线性规划和二次规划,解决优化模型。
Spass常用于统计模型,Matlab较综合,常用于编程。
算法模型归纳总结

算法模型归纳总结1. 引言算法模型在计算机科学和人工智能领域扮演着至关重要的角色。
通过对大数据的处理和分析,算法模型能够提供有效的解决方案和预测结果。
本文将对几种常见的算法模型进行归纳总结,包括线性回归、决策树、支持向量机和神经网络。
2. 线性回归线性回归是一种用于预测连续数值的算法模型。
它假设自变量和因变量之间存在线性关系,并试图找到最佳拟合直线。
线性回归的优点是计算简单,但容易受到异常值的影响。
为了解决这个问题,可以使用岭回归或Lasso回归等正则化方法进行改进。
3. 决策树决策树是一种用于分类和回归的算法模型。
它通过构建一个树形结构来生成决策规则。
每个内部节点表示一个属性或特征,每个叶节点表示一个类别或数值。
决策树的优点是易于理解和解释,但容易过拟合。
为了解决过拟合问题,可以使用剪枝技术或集成学习方法,如随机森林。
4. 支持向量机支持向量机是一种用于分类和回归的算法模型。
它通过构建一个最佳超平面来实现数据的划分。
支持向量机的优点是对于高维数据和非线性问题有较强的适应能力。
但对于大规模数据集和多类别问题,支持向量机的计算复杂度较高。
为了解决这个问题,可以使用核函数或者基于SVM的快速算法。
5. 神经网络神经网络是一种模拟人脑神经系统结构和功能的计算模型。
它由多个相互连接的神经元层组成,每个神经元通过激活函数对输入进行处理。
神经网络的优点是适用于各种问题和数据类型,但在训练过程中需要大量的计算资源和时间。
为了改善神经网络的训练效率和泛化能力,可以使用卷积神经网络或循环神经网络等改进模型。
6. 总结本文对线性回归、决策树、支持向量机和神经网络等常见的算法模型进行了归纳总结。
每种算法模型都有其适用的场景和特点,选择合适的算法模型是解决实际问题的关键。
在实际应用中,可以根据数据类型、数据规模和问题要求等因素进行选择和优化。
通过不断深入学习和实践,我们可以更好地理解和运用算法模型,提高数据分析和预测的准确性和效率。
计算机领域常用算法列表

计算机领域常用算法列表在计算机科学领域,算法是解决问题的基础工具。
各种算法的应用领域广泛,包括数据处理、搜索、排序、图形处理、机器学习等。
本文将介绍计算机领域常用的一些算法,以帮助读者了解和熟悉这些算法的基本原理和应用。
一、搜索算法1. 顺序搜索算法顺序搜索算法是最简单的搜索算法之一,其基本思想是按顺序逐个比较目标元素和列表中的元素,直到找到匹配项或搜索完整个列表。
顺序搜索算法适用于未排序的列表。
2. 二分搜索算法二分搜索算法也称为折半搜索算法,适用于已排序的列表。
其基本思想是将列表从中间切分,然后将目标元素与中间元素进行比较,根据比较结果缩小搜索范围,以达到快速搜索的目的。
3. 广度优先搜索算法广度优先搜索算法是一种图遍历算法,用于搜索图或树的结构。
它从起始节点开始,按照广度优先的方式依次访问与当前节点相邻的节点,直到找到目标节点或访问完整个图。
二、排序算法1. 冒泡排序算法冒泡排序算法是一种简单且常用的排序算法。
它通过不断比较相邻的元素并交换位置,将最大或最小的元素逐步“冒泡”到正确的位置,直到整个列表有序。
2. 快速排序算法快速排序算法是一种高效的排序算法。
它通过选择一个基准元素,将列表划分为两个子列表,其中一个子列表的元素都小于基准元素,另一个子列表的元素都大于基准元素。
然后对子列表递归地应用快速排序算法,最终得到有序列表。
3. 归并排序算法归并排序算法是一种稳定的排序算法。
它将列表划分为多个子列表,然后逐个合并子列表,直到得到完全排序的列表。
归并排序算法的核心思想是分治法,将大问题拆分为小问题并解决。
三、图算法1. 最短路径算法最短路径算法用于求解两个节点之间的最短路径。
著名的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。
迪杰斯特拉算法适用于单源最短路径问题,而弗洛伊德算法适用于所有节点对之间的最短路径问题。
2. 最小生成树算法最小生成树算法用于求解连通图的最小生成树。
其中,普里姆算法和克鲁斯卡尔算法是两种常用的最小生成树算法。
python中的常用算法

python中的常用算法Python是一种广泛使用的编程语言,它有许多内置的算法和数据结构。
下面是一些Python中常用的算法:1. 排序算法:冒泡排序选择排序插入排序快速排序归并排序2. 搜索算法:线性搜索二分搜索3. 图算法:Dijkstra的算法Bellman-Ford算法Floyd-Warshall算法4. 动态规划:斐波那契数列5. 分治算法:归并排序快速排序6. 贪心算法:找零问题最小生成树问题(如Prim或Kruskal算法)7. 深度优先搜索(DFS)与广度优先搜索(BFS):在图或树等数据结构中寻找路径或遍历节点。
8. 递归:许多问题都可以通过递归解决,例如阶乘、斐波那契数列等。
9. 迭代:与递归相对应,通过迭代可以解决许多问题,如求阶乘、斐波那契数列等。
10. 决策树和剪枝:在机器学习中经常用到,用于优化模型。
11. 机器学习算法:虽然不是传统意义上的算法,但机器学习中的许多算法在Python中都有实现,如线性回归、逻辑回归、决策树、随机森林、梯度下降等。
12. 网络流算法:在处理一些具有资源转移限制的问题时,如最大二分匹配、最短路径等,可以使用网络流算法。
13. 回溯法:用于解决一些决策问题,如八皇后问题、图的着色问题等。
14. 分治法与匹配法:用于解决一些组合优化问题,如0-1背包问题、旅行商问题等。
15. 近似算法:对于一些NP难问题,可以使用近似算法得到近似解。
如背包问题的近似解可以使用动态规划的二分法进行求解。
16. 矩阵运算和线性代数:在处理图像、机器学习等领域的问题时,矩阵运算和线性代数是常用的工具。
Python有NumPy和SciPy等库提供了强大的矩阵运算和线性代数功能。
10种常用典型算法

10种常用典型算法1. 冒泡排序(Bubble Sort):通过比较相邻元素的大小,将较大的元素交换到后面,较小的元素交换到前面,从而实现排序。
时间复杂度为O(n^2)。
2. 插入排序(Insertion Sort):将待排序的元素插入到有序子数组中的合适位置,逐步构建有序数组。
时间复杂度为O(n^2)。
3. 选择排序(Selection Sort):找到未排序部分最小的元素,并将其放到已排序部分的末尾,不断重复这个过程,直到排序完成。
时间复杂度为O(n^2)。
4. 归并排序(Merge Sort):将数组不断二分,然后将二分后的小数组进行排序合并,最终得到一个排序好的数组。
时间复杂度为O(nlogn)。
5. 快速排序(Quick Sort):从数组中选择一个基准元素,将比基准元素小的元素放到基准元素的左边,比基准元素大的元素放到基准元素的右边,然后递归地对左右两个部分进行排序。
时间复杂度为O(nlogn)。
6. 堆排序(Heap Sort):将待排序的数组构建成一个最大堆(或最小堆),然后依次从堆顶取出最大(或最小)元素,再进行调整,直到堆为空。
时间复杂度为O(nlogn)。
7. 计数排序(Counting Sort):统计数组中每个元素出现的次数,然后根据元素的出现次数将其放到相应的位置上,最终得到一个有序的数组。
时间复杂度为O(n+k),其中k为数组中的最大值。
8. 基数排序(Radix Sort):按照元素的位数将数组进行排序,从低位到高位依次排序。
时间复杂度为O(d*(n+k)),其中d为数组中元素的位数,k为基数。
9. 希尔排序(Shell Sort):将待排序的数组按照一定的间隔(增量)分成多个子数组,对每个子数组进行插入排序,然后不断减小增量,最终进行一次完整的插入排序。
时间复杂度为O(nlogn)。
10. 鸽巢排序(Pigeonhole Sort):适用于元素范围较小且元素重复较多的数组,通过统计元素的出现次数,将元素按照其出现的次数放入鸽巢中,然后按次数从小到大依次取出元素,得到一个有序的数组。
计算机科学中32个常用的基础算法

计算机科学中32个常⽤的基础算法奥地利符号计算研究所(Research Institute for Symbolic Computation,简称RISC)的Christoph Koutschan博⼠在⾃⼰的页⾯上发布了⼀篇⽂章,提到他做的⼀个调查,参与者⼤多数是计算机科学家,他请这些科学家投票选出最重要的算法,以下是这次调查的结果,按照英⽂名称字母顺序排序:1、A* 搜索算法——图形搜索算法,从给定起点到给定终点计算出路径。
其中使⽤了⼀种启发式的估算,为每个节点估算通过该节点的最佳路径,并以之为各个地点排定次序。
算法以得到的次序访问这些节点。
因此,A*搜索算法是最佳优先搜索的范例。
2、集束搜索(⼜名定向搜索,Beam Search)——最佳优先搜索算法的优化。
使⽤启发式函数评估它检查的每个节点的能⼒。
不过,集束搜索只能在每个深度中发现最前⾯的m个最符合条件的节点,m是固定数字——集束的宽度。
3、⼆分查找(Binary Search)——在线性数组中找特定值的算法,每个步骤去掉⼀半不符合要求的数据。
4、分⽀界定算法(Branch and Bound)——在多种最优化问题中寻找特定最优化解决⽅案的算法,特别是针对离散、组合的最优化。
5、Buchberger算法——⼀种数学算法,可将其视为针对单变量最⼤公约数求解的欧⼏⾥得算法和线性系统中⾼斯消元法的泛化。
6、数据压缩——采取特定编码⽅案,使⽤更少的字节数(或是其他信息承载单元)对信息编码的过程,⼜叫来源编码。
7、Diffie-Hellman密钥交换算法——⼀种加密协议,允许双⽅在事先不了解对⽅的情况下,在不安全的通信信道中,共同建⽴共享密钥。
该密钥以后可与⼀个对称密码⼀起,加密后续通讯。
8、Dijkstra算法——针对没有负值权重边的有向图,计算其中的单⼀起点最短算法。
9、离散微分算法(Discrete differentiation)10、动态规划算法(Dynamic Programming)——展⽰互相覆盖的⼦问题和最优⼦架构算法11、欧⼏⾥得算法(Euclidean algorithm)——计算两个整数的最⼤公约数。
python经典算法100例

python经典算法100例Python是一种简单易学的编程语言,它具有丰富的库和模块,可以实现各种算法。
下面将介绍100个经典的Python算法例子,帮助读者更好地理解和掌握Python编程。
1. 二分查找算法:在有序数组中查找指定元素的位置。
2. 冒泡排序算法:对数组进行排序,每次比较相邻的两个元素并交换位置。
3. 快速排序算法:通过选择一个基准元素,将数组分为两部分,递归地对两部分进行排序。
4. 插入排序算法:将数组分为已排序和未排序两部分,每次从未排序部分选择一个元素插入到已排序部分的正确位置。
5. 选择排序算法:每次从未排序部分选择最小的元素放到已排序部分的末尾。
6. 归并排序算法:将数组分为两部分,递归地对两部分进行排序,然后将两部分合并。
7. 堆排序算法:通过构建最大堆或最小堆,将数组进行排序。
8. 计数排序算法:统计数组中每个元素的出现次数,然后按照次数进行排序。
9. 桶排序算法:将数组分为多个桶,每个桶内部进行排序,然后将桶中的元素按照顺序合并。
10. 基数排序算法:按照元素的位数进行排序,从低位到高位依次进行。
11. 斐波那契数列算法:计算斐波那契数列的第n个数。
12. 阶乘算法:计算一个数的阶乘。
13. 最大公约数算法:计算两个数的最大公约数。
14. 最小公倍数算法:计算两个数的最小公倍数。
15. 素数判断算法:判断一个数是否为素数。
16. 矩阵相加算法:计算两个矩阵的和。
17. 矩阵相乘算法:计算两个矩阵的乘积。
18. 斐波那契堆算法:实现斐波那契堆的插入、删除和合并操作。
19. 最短路径算法:计算图中两个节点之间的最短路径。
20. 最小生成树算法:计算图中的最小生成树。
21. 拓扑排序算法:对有向无环图进行拓扑排序。
22. 最大流算法:计算网络中的最大流。
23. 最小费用流算法:计算网络中的最小费用流。
24. 最大子序列和算法:计算数组中连续子序列的最大和。
25. 最长递增子序列算法:计算数组中最长递增子序列的长度。
计算机常见的32种算法

计算机常见的32种算法
1.冒泡排序算法
2.选择排序算法
3.插入排序算法
4.希尔排序算法
5.归并排序算法
6.快速排序算法
7.堆排序算法
8.计数排序算法
9.桶排序算法
10.基数排序算法
11.贪心算法
12.动态规划算法
13.分治算法
14.回溯算法
15.图的深度优先算法(DFS)
16.图的广度优先算法(BFS)
17. Kruskal算法(最小生成树)
18. Prim算法(最小生成树)
19. Floyd-Warshall算法(最短路径)
20. Dijkstra算法(最短路径)
21.拓扑排序算法
22. 找出最大子数组的算法(Kadane算法)
23.最长公共子序列算法
24.最长递增子序列算法
25.最长回文子串算法
26.哈夫曼编码算法
27. Rabin-Karp算法(字符串匹配)
28. Boyer-Moore算法(字符串匹配)
29.KMP算法(字符串匹配)
30.后缀数组算法
31.基于哈希表的查找算法
32.基于二分查找的查找算法
需要注意的是,以上列举的只是计算机中常见的算法之一,实际上还存在着很多其他的算法。
每种算法都有其特定的应用场景和解决问题的方法。
对于每种算法的原理和具体实现细节,可以进一步深入学习和研究。
C语言经典算法大全精选

C语言经典算法大全精选1.排序算法1.1冒泡排序:通过不断交换相邻元素的位置,将最大(最小)值“冒泡”到序列的末尾(开头)。
1.2插入排序:将未排序的元素逐个插入已排序的序列中,保持序列始终有序。
1.3选择排序:每次从未排序的元素中选择最小(最大)的元素,放到已排序序列的末尾(开头)。
1.4快速排序:通过递归地将序列分割为较小和较大的两部分,然后分别对两部分进行排序。
1.5归并排序:将序列递归地分割为两个子序列,分别排序后再将结果合并。
1.6堆排序:构建最大(最小)堆,然后逐步将堆顶元素与最后一个元素交换,并调整堆结构。
2.查找算法2.1顺序查找:逐个比较元素,直到找到目标元素或遍历完整个序列。
2.2二分查找:在有序序列中,通过不断缩小查找范围,找到目标元素。
2.3插值查找:根据目标元素与序列中最大、最小元素的关系,按比例选择查找范围。
2.4哈希查找:利用哈希函数将目标元素映射到一个唯一的位置,从而快速定位目标元素。
3.字符串算法3.1字符串匹配算法:在文本串中查找给定的模式串,并返回匹配位置。
3.2字符串翻转:将一个字符串逆序输出。
3.3字符串压缩:将连续出现多次的字符压缩为一个字符,并输出压缩后的字符串。
3.4字符串拆分:按照指定的分隔符将字符串拆分为多个子串,并返回子串列表。
3.5字符串反转单词:将一个句子中的单词顺序逆序输出。
4.图算法4.1深度优先:从起始顶点出发,递归地访问所有能到达的未访问顶点。
4.2广度优先:从起始顶点出发,逐层地访问与当前层相邻的未访问顶点。
4.3最小生成树:找到连接所有顶点的具有最小权值的无环边集合。
4.4最短路径:找到两个顶点之间最短路径的权值和。
4.5拓扑排序:找到一个顶点的线性序列,满足所有有向边的起点在终点之前。
5.数学算法5.1质数判断:判断一个数是否为质数(只能被1和自身整除)。
5.2求最大公约数:找到两个数的最大公约数。
5.3求最小公倍数:找到两个数的最小公倍数。
常用算法模板

第三阶段: 参加一些比赛,查漏补缺。
请求出错错误代码503请尝试刷新页面重试
常用算法模板
第一阶段: 经典常用算法,下面的算法要打上十到二十遍,同时自己精简代码。 1.二分查找 2.大数加减乘除 3.最小生成树(kruscal、prim) 4.最短路(floyd、dijstra、bellmanford) 5.bfs、dfs、hash表 6.任意进制间的转换 7.sort、qsort 8.辗转相除、线段交点、多边形面积
oi算法模板

oi算法模板OI(竞赛信息学)是指竞赛化的信息学学科,通过算法设计和程序编写的方式,解决实际问题。
在OI竞赛中,掌握一些常用的算法模板是非常重要的,因为这些模板可以帮助选手快速解决问题,提高编程效率。
下面是一些常用的OI算法模板,供参考:1. 排序算法模板:- 冒泡排序:依次比较相邻元素,交换位置直到队列有序;- 快速排序:选择一个基准元素,将小于基准的元素置于其左侧,大于基准的元素置于其右侧,再对两侧递归进行快速排序;- 归并排序:将待排序队列划分成两个子队列,对子队列进行排序后再合并。
2. 图论算法模板:- 最短路径算法:例如Dijkstra算法和Floyd算法,分别用于求解单源最短路径和多源最短路径问题;- 最小生成树算法:例如Prim算法和Kruskal算法,分别用于求解无向图的最小生成树问题;- 拓扑排序:用于有向无环图中,将所有顶点排成一个线性序列,使得图中任意一对顶点u、v满足u在v之前。
3. 动态规划算法模板:- 01背包问题:给定n件物品,每件物品的重量为w,价值为v,背包的容量为C,求解背包可以装入的物品的最大总价值;- 最长公共子序列(LCS):给定两个序列X和Y,求解X和Y的最长公共子序列的长度;- 最长递增子序列(LIS):给定一个序列A,求解A的最长递增子序列的长度。
4. 字符串算法模板:- KMP算法:用于在一个文本串S中查找一个模式串P的出现位置,时间复杂度为O(n+m);- Manacher算法:用于求解一个字符串中的最长回文子串,时间复杂度为O(n);- Trie树:一种用于高效存储和搜索大量字符串的数据结构,常用于字符串匹配问题。
除了以上介绍的算法模板,还有许多其他常用的算法模板,如最大流算法、二叉树遍历算法、并查集算法等。
选手可以根据题目的要求和具体情况选择合适的算法模板来解决问题。
对于OI算法模板的学习和掌握,建议选手进行一些练习和实战。
可以参加一些在线的编程资源和平台,如Codeforces、AtCoder和LeetCode等,通过参加竞赛和练习题来提高自己的算法能力。
Python 基础算法大全

Python 基础算法1. 排序算法-冒泡排序:从左到右不断交换相邻逆序的元素,在一轮的操作中至少可以让一个元素移动到它应该在的位置,因此需要进行n 轮的操作。
时间复杂度O(n^2)。
-选择排序:从未排序部分选一个最小的元素放到已排序部分末尾,直到所有元素都被排序。
时间复杂度O(n^2)。
-插入排序:将数组分为已排序和未排序两部分,每次取未排序部分的第一个元素并插入到已排序部分合适的位置上。
时间复杂度O(n^2)。
-快速排序:通过递归地将待排序数组分割成两部分来实现排序,每一轮将数组划分成两个子数组,一部分小于基准数,另一部分大于等于基准数,然后分别对这两个子数组进行快速排序。
时间复杂度平均O(nlogn),最坏情况下退化成O(n^2)。
-归并排序:采用分治思想,将待排序数组不断二分为两个子数组,对于每个子数组采用递归方式进行排序,最后将排序好的子数组再合并起来。
时间复杂度O(nlogn)。
2. 查找算法-线性查找:遍历整个数组或列表,查找目标元素。
时间复杂度O(n)。
-二分查找:针对有序数组或列表,每次将待查找区间缩小一半,直到找到目标元素或区间为空。
时间复杂度O(logn)。
3. 字符串匹配算法-暴力匹配算法:从主串起始位置和模式串起始位置开始比较,每次比较移动一位,直到找到匹配的字符串或者主串结束。
时间复杂度O(m*n)。
- KMP算法:通过部分匹配表,减少了在不匹配时,模式串的滑动距离。
时间复杂度O(m+n)。
4. 图论算法-最短路径算法:Dijkstra算法、Bellman-Ford算法、Floyd算法。
-最小生成树算法:Prim算法、Kruskal算法。
-深度优先搜索(DFS):递归地搜索图的所有节点,遍历子节点后回溯到父节点继续搜索。
时间复杂度O(n+m)。
-广度优先搜索(BFS):从起点开始向外扩展,先访问邻居节点,再访问邻居的邻居节点,以此类推。
时间复杂度O(n+m)。
5. 动态规划-最长公共子序列(LCS):给定两个字符串,找到两个字符串中都出现过的最长子序列。
计算机10大经典算法

计算机10⼤经典算法算法⼀:快速排序法快速排序是由东尼·霍尔所发展的⼀种排序算法。
在平均状况下,排序 n 个项⽬要Ο(n log n)次⽐较。
在最坏状况下则需要Ο(n2)次⽐较,但这种状况并不常见。
事实上,快速排序通常明显⽐其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在⼤部分的架构上很有效率地被实现出来。
快速排序使⽤分治法(Divide and conquer)策略来把⼀个串⾏(list)分为两个⼦串⾏(sub-lists)。
算法步骤:1 .从数列中挑出⼀个元素,称为 “基准”(pivot),2. 重新排序数列,所有元素⽐基准值⼩的摆放在基准前⾯,所有元素⽐基准值⼤的摆在基准的后⾯(相同的数可以到任⼀边)。
在这个分区退出之后,该基准就处于数列的中间位置。
这个称为分区(partition)操作。
3. 递归地(recursive)把⼩于基准值元素的⼦数列和⼤于基准值元素的⼦数列排序。
递归的最底部情形,是数列的⼤⼩是零或⼀,也就是永远都已经被排序好了。
虽然⼀直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它⾄少会把⼀个元素摆到它最后的位置去。
算法⼆:堆排序算法堆排序(Heapsort)是指利⽤堆这种数据结构所设计的⼀种排序算法。
堆积是⼀个近似完全⼆叉树的结构,并同时满⾜堆积的性质:即⼦结点的键值或索引总是⼩于(或者⼤于)它的⽗节点。
堆排序的平均时间复杂度为Ο(nlogn) 。
算法步骤:1.创建⼀个堆H[0..n-1]2.把堆⾸(最⼤值)和堆尾互换3. 把堆的尺⼨缩⼩1,并调⽤shift_down(0),⽬的是把新的数组顶端数据调整到相应位置4. 重复步骤2,直到堆的尺⼨为1算法三:归并排序归并排序(Merge sort,台湾译作:合并排序)是建⽴在归并操作上的⼀种有效的排序算法。
该算法是采⽤分治法(Divide and Conquer)的⼀个⾮常典型的应⽤。
16个ACM经典算法介绍

16个ACM经典算法介绍一、排序算法:1.冒泡排序:基于比较的排序算法,通过不断交换相邻元素将最大元素逐渐向后移动。
2.插入排序:基于比较的排序算法,通过将元素逐个插入到已排好序的部分中,最终得到完全有序的序列。
3.归并排序:基于分治的排序算法,将待排序序列划分为一系列子序列,然后将子序列进行合并,最终得到完全有序的序列。
4.快速排序:基于分治的排序算法,通过选择一个基准元素将序列划分为两部分,然后递归地对两部分进行排序。
5.堆排序:基于堆的排序算法,通过构建最大堆或最小堆来实现排序。
二、查找算法:6.二分查找:基于有序序列的查找算法,通过将待查找值与序列中间元素进行比较,逐渐缩小查找范围。
7.哈希表:基于哈希函数的查找算法,通过将键值对存储在哈希表中,实现高效的查找。
三、图算法:8.深度优先(DFS):基于栈的算法,通过递归地访问顶点的邻接顶点,实现图的遍历。
9.广度优先(BFS):基于队列的算法,通过访问顶点的邻接顶点,实现图的遍历。
10. 最小生成树算法:用来求解无向图的最小生成树,常用的有Prim算法和Kruskal算法。
11. 最短路径算法:用来求解有向图或带权重的无向图的最短路径,常用的有Dijkstra算法和Floyd-Warshall算法。
四、动态规划算法:12.最长上升子序列(LIS):用来求解一个序列中最长严格递增子序列的长度。
13.背包问题:用来求解在给定容量下,能够装入尽量多的物品的问题。
五、字符串算法:14.KMP算法:用来在一个文本串S中查找一个模式串P的出现位置的算法,通过预处理模式串,利用已经匹配过的子串,跳过一定长度进行下一轮匹配。
15. Boyer-Moore算法:用来在一个文本串S中查找一个模式串P的出现位置的算法,通过从模式串末尾开始匹配,利用好后缀和坏字符规则,跳过一定长度进行下一轮匹配。
16.字符串匹配算法:用来在一个文本串S中查找多个模式串的出现位置的算法,常用的有AC自动机和后缀树。
最常用的10大算法

最常⽤的10⼤算法1.String/Array/Matrix在Java中,String是⼀个包含char数组和其它字段、⽅法的类。
如果没有IDE⾃动完成代码,下⾯这个⽅法⼤家应该记住:toCharArray() //get char array of a StringArrays.sort() //sort an arrayArrays.toString(char[] a) //convert to stringcharAt(int x) //get a char at the specific indexlength() //string lengthlength //array sizesubstring(int beginIndex)substring(int beginIndex, int endIndex)Integer.valueOf()//string to integerString.valueOf()/integer to stringString/arrays很容易理解,但与它们有关的问题常常需要⾼级的算法去解决,例如动态编程、递归等。
下⾯列出⼀些需要⾼级算法才能解决的经典问题:2.链表在Java中实现链表是⾮常简单的,每个节点都有⼀个值,然后把它链接到下⼀个节点。
class Node {int val;Node next;Node(int x) {val = x;next = null;}}⽐较流⾏的两个链表例⼦就是栈和队列。
栈(Stack)class Stack{Node top;public Node peek(){if(top != null){return top;}return null;}public Node pop(){if(top == null){return null;}else{Node temp = new Node(top.val);top = top.next;return temp;}}public void push(Node n){if(n != null){n.next = top;top = n;}}}队列(Queue)class Queue{Node first, last; public void enqueue(Node n){if(first == null){first = n;last = first;}else{last.next = n;last = n;}} public Node dequeue(){if(first == null){return null;}else{Node temp = new Node(first.val);first = first.next;return temp;}}}值得⼀提的是,Java标准库中已经包含⼀个叫做Stack的类,链表也可以作为⼀个队列使⽤(add()和remove())。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
复赛算法模块信息学奥赛组对于NOIP,基础是相当重要的,在3个小时之内做完4道题,那么就要求我们有相当快的速度。
特别是对于一些简单的、常用的算法模块,一定要要熟练掌握并灵活运用。
由于NOIP是一个比较基础的比赛,因此基本算法的掌握尤为重要,所以要求能够把这些基本的模块快速、准确的移植到不同的程序中,才能在稳中取胜基本算法模块中最重要的是基本程序框架,也就是说,要养成适合于自己的程序风格,这样对于程序编写的速度与程序的准确度都有较大的提高。
小议竞赛的准备和考试技巧1、良好的心态。
无论竞赛多么重要,都不要在考试的时候考虑考试之前或以后的事,这很重要……2、充足的睡眠和营养。
竞赛之前睡好觉,吃好饭,多吃甜食(据我们老师说在吃甜食后15分钟和2小时会各出现一次血糖高峰,会有比较好的竞技状态)。
还有,宁可撒尿也不要口渴……口渴会严重影响思路……而尿素有兴奋作用,有利无害……3、正确的时间安排。
一般来说应该先想完所有的题再开始做,但有的题想不出来的时候一定要给想出来的题留出时间。
4、算法的学习。
一般的DFS/BFS、贪心、各种DP、二分法、排序、lr论文中的各种奇特算法、最短路、最长路、图的DFS/BFS、最大匹配,最大最小匹配、最佳匹配、差分限制系统、最长不xx子序列、高斯消元、数论算法……5、数据结构的学习。
Hash、并查集、邻接表、边表、堆、树状数组和线段树及它们的多维形式、链表、单词查找树……6、关于混分:超时的搜索/DP往往能比错误的贪心得到更多的分。
7、数学很重要。
比如母函数……8、专用的方法胜于通用的方法。
9、好的题目往往不能直接用经典算法解决。
10、真正难题的标程往往很短。
11、如果n很大,用汇编写的O(n^2)的程序绝对不如用QB写的O(n)的程序快。
12、如果n很小,利用压缩存储提高速度的O(n^2)的算法有可能比一般的O(n)算法快。
13、如果一个数学问题很复杂,那么看结果找规律有可能比数学推导快。
14、不要总把logn忽略掉。
15、即使是多项式算法,有时也可以加入很有效的剪枝。
16、做一道好题胜过做n道烂题,但如果不做烂题,可能会影响做好题的速度。
模块目录页码一、排序 (4)1.选择排序2.插入排序3.冒泡排序4.快速排序5.堆排序6.归并排序7.线性时间排序二、高精度 (6)1.高精度比较2.高精度加法3.高精度减法4.单精度乘法5.高精度乘法6.单精度除法7.高精度除法8.进制转换三、数论 (10)1.欧几里德算法2.扩展欧几里德3.求最小公倍数4.求解线形同余方程5.素数的判断6.素数的生成四、排列组合 (12)1.排列生成算法2.组合生成算法3.排列按序生成法4.排列字典序生成法五、图论 (15)1.图的读入2.深度优先搜索3.广度优先搜索4.强连同分量5.拓扑排序6.最小生成树7.最短路径六、背包问题 (21)1.装满背包2.一维价值最大背包3.二位价值最大背包一、排序算法vara:array[1..maxn]of longint;——排序对象1.选择排序——Select_sortprocedure select_sort;beginfor i:=1 to n-1 dofor j:=i+1 to n doif a[i]>a[j] thenbegin temp:=a[i];a[i]:=a[j];a[j]:=temp;end;end;2.插入排序——Insert_sortprocedure insert_sort;beginfor i:=2 to n dobeginkey:=a[i];j:=i-1;while (key<a[j])and(j>0) do begin a[j+1]:=a[j];dec(j);end;a[j+1]:=key;end;end;3.冒泡排序——Bubble_sortprocedure bubble_sort;beginfor i:=1 to n-1 dofor j:=n downto i+1 doif a[j]<a[j-1] thenbegin temp:=a[j];a[j]:=a[j-1];a[j-1]:=temp;end;end;4.快速排序——Quick_sortprocedure qsort(s,t:longint);vari,j,x:longint;begini:=s;j:=t;x:=a[(i+j)div 2];repeatwhile a[i]<x do inc(i); {找左边比他大的}while a[j]>x do dec(j);{找右边比他小的}if i<=j then{交换}begintemp:=a[i];a[i]:=a[j];a[j]:=temp;inc(i);dec(j);end;until i>j;if s<j then qsort(s,j);if i<t then qsort(i,t);end;5.堆排序——Heap_sortprocedure heap(i,n:longint);{将第i个元素向下筛} varj,x:longint;beginj:=i*2;x:=a[i];while j<=n dobeginif (j<n)and(a[j]<a[j+1]) then inc(j);if x<a[j]then begina[i]:=a[j];i:=j;j:=i*2;endelse j:=n+1;end;a[i]:=x;end;procedure heap_sort;beginfor i:=n div 2 downto 1 do heap(i,n);for i:=n downto 2 dobegintemp:=a[i];a[i]:=a[1];a[1]:=temp;heap(1,i-1);end;end;6.归并排序——Merge_sortprocedure mergesort(s,t:longint);varm,i,j,k:longint;beginif t-s=0 then exit;m:=(s+t)div 2;mergesort(s,m);mergesort(m+1,t);for i:=1 to m-s+1 do b[i]:=a[s+i-1];for j:=m+1 to t do c[j-m]:=a[j];i:=1;j:=1;b[m-s+2]:=max;c[t-m+1]:=max;for k:=s to t doif b[i]<c[j]then begin a[k]:=b[i];inc(i);endelse begin a[k]:=c[j];inc(j);end;end;7.线性时间排序——基数排序、计数排序、桶排序二、高精度算法——High_precisionconstmaxcount=进制位maxlen=记录高精度数组大小typebignum=array[0..maxlen]of longint;0为位数1.高精度比较function compare(a,b:bignum):longint;beginwhile a[a[0]]=0 do dec(a[0]);{检查位数是否正确}while b[b[0]]=0 do dec(b[0]);while a[a[0]+1]>0 do inc(a[0]);while b[b[0]+1]>0 do inc(b[0]);if a[0]>b[0] then exit(1);if a[0]<b[0] then exit(-1);for i:=a[0] downto 1 dobeginif a[i]>b[i] then exit(1);if a[i]<b[i] then exit(-1);end;exit(0);end;2.高精度加法procedure add(a,b:bignum;var c:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c[0]:=1;if a[0]>b[0]then c[0]:=a[0]else c[0]:=b[0];for i:=1 to a[0] do inc(c[i],a[i]);for i:=1 to b[0] do inc(c[i],b[i]);for i:=1 to c[0] dobegininc(c[i+1],c[i] div maxcount);c[i]:=c[i] mod 10;end;while c[c[0]+1]>0 dobegininc(c[0]);inc(c[c[0]+1],c[c[0]] div maxcount);c[c[0]]:=c[c[0]] mod maxcount;end;end;3.高精度减法procedure minus(a,b:bignum;var c:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c[0]:=a[0];for i:=1 to c[0] do c[i]:=a[i]-b[i];for i:=1 to c[0] doif c[i]<0 thenbegindec(c[i+1]);inc(c[i],maxcount);end;while (c[0]>1)and(c[c[0]]=0) do dec(c[0]);end;4.单精度乘法procedure mulnum(a:bignum;x:longint,var c:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c[0]:=a[0];for i:=1 to c[0] do c[i]:=a[i]*x;for i:=1 to c[0] dobegininc(c[i+1],c[i] div maxcount);c[i]:=c[i] mod 10;end;while c[c[0]+1]>0 dobegininc(c[0]);inc(c[c[0]+1],c[c[0]] div maxcount);c[c[0]]:=c[c[0]] mod maxcount;end;end;5.高精度乘法procedure mul(a,b:bignum;var c:bignum);vari,j:longint;beginfillchar(c,sizeof(c),0);c[0]:=a[0]+b[0]-1;for i:=1 to a[0] dofor j:=1 to b[0] doinc(c[i+j-1],a[i]*b[j]);for i:=1 to c[0] dobegininc(c[i+1],c[i] div maxcount);c[i]:=c[i] mod 10;end;while c[c[0]+1]>0 dobegininc(c[0]);inc(c[c[0]+1],c[c[0]] div maxcount);c[c[0]]:=c[c[0]] mod maxcount;end;end;6.单精度除法function divnum(a:bignum;x:longint;var c:bignum):longint;vari,temp:longint;beginfillchar(c,sizeof(c),0);c[0]:=a[0];temp:=0;for i:=a[0] downto 1 dobegintemp:=temp*maxcount+a[i];c[i]:=temp div x;temp:=temp mod x;end;while (c[o]>1)and(c[c[0]]=0) do dec(c[0]);exit(temp);end;7.高精度除法procedure div(a,b:bignum;var c,d:bignum);vari:longint;beginfillchar(c,sizeof(c),0);c[0]:=a[0]-b[0]+1;fillchar(d,sizeof(d),0);d[0]:=1;for i:=c[0] downto 1 dobeginc[i]:=maxcount;repeatdec(c[i]);mul(c,b,temp);until compare(a,temp)>=0;end;while (c[o]>1)and(c[c[0]]=0) do dec(c[0]);minus(a,temp,d);end;8.进制转换10进制数用bignum记,maxcount=10k进制数用string记constrepchar:array[0..35]of string=(‘0’,‘1’,’2’,……,’a’,’b’,……,’z’);——数码对应的字符repnum:array[48..122]of longint=(0,1,2……,34,35);——字符的ASCCI码对应的数码k进制转十进制:procedure change_to_ten(s:string;k:longint):bignum;vari,l:longint;temp:bignum;beginl:=length(s);temp[0]:=1;temp[1]:=repnum[ord(s[l])];for i:=1 to l-1 dobegininc(temp[1],repnum[ord(s[l-i])]);mulnum(temp,k);end;exit(temp);end;十进制转k进制:procedure change_to_k(num:bignum;k:longint):string;vari,temp:longint;s:string;beginif (num[0]=1)and(num[1]=0) then exit(‘0’);while not((num[0]=1)and(num[1]=0)) dobegintemp:=divnum(num,k,num);s:=repchar[temp]+s;end;exit(s);end;三、数论算法1.求最大公约数——gcd(欧几里德算法)递归(recursion):function gcd(a,b:longint):longint;beginif b=0 then exit(a);exit(gcd(b,a mod b));end;非递归(iterative):function gcd(a,b:longint):longint;vart:longint;beginwhile b<>0 dobegint:=a;a:=b;b:=t mod b;end;exit(a);end;2.扩展欧几里德算法function extended_euclid(a,b:longint;var x,y:longint):longint;varp,q:longint;beginif b=0 thenbeginx:=1;y:=0;exit(a);end;p:=extended_euclid(b, a mod b,x,y);q:=x;x:=y;y:=q-a div b *y;exit(p);end;3.求最小公倍数k:=a*b div gcd(a,b);4.求解线性同余方程typeansnode=recordansnum:longint;——解的个数num:array[1..maxnnum]of longint;——解end;procedure modular_linear_equation(a,b,n:longint;var ans:ansnode);vard,i,x,y,temp:longint;begind:=extended_euclid(a,n,x,y);if b mod d <>0then ans.ansnum:=0else beginans.ansnum:=d;temp:=(x*(b div d))mod n;for i:=1 to d do ans.num[i]:=(temp+i*(n div d))mod n;end;end;5.素数的判断function prime_bool(x:longint):boolean;vari:longint;beginfor i:=2 to trunc(sqrt(x)) doif x mod i=0 then exit(false);exit(true);end;6.素数的生成maxnum=生成质数的范围maxprime=对应范围中的质数个数varprime:array[0..maxprime]of longint;——存储质数bool:array[1..maxnnum]of boolean;——存储每个数是不是质数procedure prime_make;vari,j:longint;beginfillchar(bool,sizeof(bool),0);i:=2;while i<=maxnnum dobeginif not p[i] thenbeginj:=2*i;while i<=maxnnum dobeginp[j]:=true;inc(j,i);end;inc(prime[0]);prime[prime[0]]:=i;end;inc(i);end; end;四、排列组合算法1.排列生成算法——m的n排列vara:array[0..maxn]of longint;——排列方案b:array[0..maxm]of boolean;——每个数是否被用过递归(recursion):procedure make_permutation_recursion(t:longint)vari:longint;beginif t=n+1 thenbeginwrite(a[1]);for i:=2 to n do write(‘‘,a[i]);writeln;exit;end;for i:=1 to m doif not b[i] thenbeginb[i]:=true;a[t]:=i;make(t+1);b[i]:=false;end;end;非递归(iterative):procedure make_permutation_iterative(m,n:longint);vari,j:longint;begini:=1;a[1]:=0;repeatj:=a[i]+1;while (j<=m)and(b[j]) do inc(j);if j<=mthen begina[i]:=j;b[j]:=true;if i=nthen beginwrite(a[1]);for j:=2 to n do write(‘‘,a[j]);writeln;b[a[n]]:=false;endelse begininc(i);a[i]:=0;end;endelse begindec(i);b[a[i]]:=false;end;until i=0;end;2.组合生成算法——m的n组合procedure make_combination(t:longint)vari:longint;beginif t=n+1 thenbeginwrite(a[1]);for i:=2 to n do write(‘‘,a[i]);writeln;exit;end;for i:=a[t-1] to m doif not b[i] thenbeginb[i]:=true;a[t]:=i;make(t+1);b[i]:=false;end;end;3.排列按序生成法constpower:array[1..maxn]of longint=(…);power[i]为i的阶乘typepermutationnode=array[1..maxn]of longint;——排列方案求n的全排的字典序:function get_number(n:longint;a:permutationnode):longint;varb:array[1..maxn]of longint;i,j,s:longint;beginfor i:=1 to n do b[i]:=i-1;s:=0;for i:=1 to n-1 dobegininc(s,b[a[i]]*power[n-i]);for j:=a[i]+1 to n do dec(b[j]);end;exit(s+1);end;求字典序为m的n的全排:function get_permutation(m,n:longint;):permutationnode;varuse:array[1..maxn]of boolean;a:array[0..maxn]of longint;temp:permutationnode;begindec(m);for i:=1 to n-1 dobegina[i]:=m mod (i+1);m:=m div (i+1);end;a[0]:=0;for i:=1 to n dobeginj:=0;for k:=1 to a[n-i]+1 dobegininc(j);while use[j] do inc(j);end;temp[i]:=j;use[j]:=true;end;exit(temp);end;4.排列字典序生成法——求n的某个全排的下m个字典序排列proceduremake_next(n,m:longint;a:permutationnode):permutationnode;vari,j,k,t,temp:longint;beginfor t:=1 to m dobegini:=n;while (i>1)and(a[i]<a[i-1]) do dec(i);j:=n;while a[j]<a[i-1] do dec(j);temp:=a[i-1];a[i-1]:=a[j];a[j]:=temp;for k:=i to (i+n)div 2 dobegintemp:=a[k];a[k]:=a[n+i-k];a[n+i-k]:=temp;end;end;exit(a); end;五、图论算法1.图的读入以点为基础读入(没有特殊说明,一般以此方法读入):varvetex:array[1..maxn,0..maxn]of longint;——邻接表,记录与那些点相连map:array[1..maxn,1..maxn]of longint;——邻接矩阵,记录点点之间的距离procedure initgraph;vari,u,v,c:longint;beginreadln(n,e);for i:=1 to e dobeginreadln(u,v,c);inc(vetex[u,0]);vetex[u,vetex[u,0]]:=v;map[u,v]:=c;end;end;以边为基础读入:typenode=recordu,v,w:longint;——u为起点,v为终点,w为权end;varvetex:array[1..maxe]of node;——记录边procedure initgraph;vari:longint;beginreadln(n,e);for i:=1 to e dowith vetex[i] do readln(u,v,w);end;2.深度优先搜索——DFSvartime:longint;——时间flag:array[1..maxn]of boolean;——是否标记procedure DFS(t:longint);vari:longint;begininc(time);gettime[t]:=time;flag[t]:=true;for i:=1 to vetex[t,0] doif not flag[vetex[t,i]] thenbeginfrom[vetex[t,i]]:=t;dep[vetex[t,i]]:=dep[t]+1;DFS(vetex[t,i]);end;inc(time);finishtime[t]:=time;end;3.广度优先搜索——BFSprocedure BFS(t:longint);vartime,open,closed,i,v:longint;flag:array[1..maxn]of boolean;x0:array[1..maxn]of longint;beginfillchar(flag,sizeof(flag),0);open:=0;closed:=1;x0[1]:=t;dep[t]:=0;time:=1;flag[t]:=true;flagtime[t]:=1;repeatinc(open);v:=x0[open];inc(time);finishtime[v]:=time;for i:=1 to vetex[v,0] doif not flag[vetex[v,i]] thenbegininc(closed);x0[closed]:=vetex[v,i];flag[vetex[v,i]]:=true;dep[vetex[v,i]]:=dep[v]+1;inc(time);gettime[vetex[v,i]]:=time;end;until open>=closed;end;4.强连通分量varconnected:array[1..maxn,0..maxn]of longint;——connect[i,0]为此分量包含的节点数total:longint;——强连同分量的个数procedure strongly_connected;vari,time:longint;flag:array[1..maxn]of boolean;sign:array[1..maxn]of longint;procedure sort1(t:longint);vari:longint;beginflag[t]:=true;for i:=1 to n doif (map[t,i]<>0)and(not flag[i]) thensort1(i);inc(time);sign[time]:=t;end;procedure sort2(t:longint);vari:longint;beginflag[t]:=true;for i:=1 to n doif (not flag[i])and(map[i,t]<>0) thensort2(i);inc(connected[total,0]);connected[total,conneted[total,0]]:=t;end;beginfillchar(flag,sizeof(flag),0);for i:=1 to n doif not flag[i] thensort1(i);for i:=n downto 1 doif not flag[sign[i]] thenbegininc(total);sort(sign[i]);end;end;5.拓扑排序procedure topological_sort;vari,open,closed:longint;flag:array[1..maxn]of boolean;beginopen:=0;closed:=0;for i:=1 to n doif inv[i]=0 thenbegininc(closed);flag[i]:=true;AOV[closed]:=i;end;if closed=0 then exit{error};repeatinc(open);v:=AOV[open];for i:=1 to vetex[v,0] doif not flag[vetex[v,i]] thenbegindec(inv[vetex[v,i]]);if inv[vetex[v,i]]=0 thenbegininc(closed);AOV[closed]:=vetex[v,i];flag[vetex[v,i]]:=true;end;end;until open=closed;if closed<n then exit{error};end;6.最小生成树Prime:procedure prime_normal;vari,j,min,mj:longint;flag:array[1..maxn]of boolean;lowcost:array[1..maxn]of longint;beginfillchar(lowcost,sizeof(lowcost),$5F);lowcost[1]:=0;flag[1]:=true;for i:=1 to v[1,0] dolowcost[v[1,i]]:=map[1,v[1,i]];for i:=2 to n dobeginmin:=maxlongint;for j:=1 to n doif (not flag[j])and(lowcost[j]<min) thenbeginmin:=lowcost[j];mj:=j;end;flag[mj]:=true;inc(totallen,min);for j:=1 to v[mj,0] doif (not flag[v[mj,j]])and(lowcost[v[mj,j]]>map[mj,v[mj,j]]) then lowcost[v[mj,j]]:=map[mj,v[mj,j]];end;end;Kruskal——以边为基础读入:procedure kruskal;varset1,set2,vetex_pointer,last_set_num:longint;function find(x:longint):longint;beginif father[x]=x then find:=father[x]else begin father[x]:=find(father[x]);find:=father[x];end;end;beginqsort(1,e);——对vetex以w为关键字从小到大排序for i:=1 to n do father[i]:=i;vetex_pointer:=1;last_set_num:=n;while (last_set_num>1)and(vetex_pointer<=e) dobeginset1:=find(vetex[vetex_pointer].u);set2:=find(vetex[vetex_pointer].v);if set1<>set2 thenbegininc(totallen,vetex[vetex_pointer].w);dec(last_set_num);father[set1]:=set2;end;inc(vetex_pointer);end;writeln(totallen);end;7.最短路径Dijktra:procedure Dijkstra(s:longint);vari,j,min,mi:longint;beginfillchar(shortest,sizeof(shortest),$5F);shortest[s]:=0;for i:=1 to n dobeginmin:=max;for j:=1 to n doif (not flag[j])and(shortest[j]<min) thenbegin min:=shortest[j];mi:=j;end;flag[mi]:=true;for j:=1 to vetex[mi,0] doif (not flag[vetex[mi,j]])and(shortest[vetex[mi,j]]>min+map[mi,vetex[mi,j]]) then shortest[vetex[mi,j]]:=min+map[mi,vetex[mi,j]];end;end;Floyd:procedure Floyd;vari,j,k:longint;beginfillchar(len,sizeof(len),$5F);for i:=1 to n dobeginlen[i,i]:=0;for j:=1 to vetex[i,0] dolen[i,vetex[i,j]]:=map[i,vetex[i,j]];end;for k:=1 to n dofor i:=1 to n dofor j:=1 to n doif len[i,k]+len[k,j]<len[i,j] thenlen[i,j]:=len[i,k]+len[k,j];end;Bellman-ford——以边为基础读入:procedure Bellman-ford(s:longint);vari,j:longint;bool:boolean;beginfillchar(shortest,sizeof(shortest),$5F);shortest[s]:=0;bool:=true;for i:=1 to n-1 doif bool thenbeginbool:=false;for j:=1 to e doif shortest[vetex[j].v]>shortest[vetex[j].u]+vetex[j].w thenbeginshortest[vetex[j].v]:=shortest[vetex[j].u]+vetex[j].w;bool:=true;end;end;for j:=1 to e doif shortest[vetex[j].v]>shortest[vetex[j].u]+vetex[j].w then exit(flase);exit(true);end;SPFA:procedure SPFA(s:longint);varu,i:longint;x0:array[1..maxn]of longint;beginfillchar(shortest,sizeof(shortest),$5f);fillchar(flag,sizeof(flag),0);open:=0;closed:=1;x0[1]:=s;shortest[s]:=0;flag[s]:=true;repeatinc(open);u:=x0[open];for i:=1 to vetex[u,0] doif shortest[vetex[u,i]]<shortest[u]+map[u,vetex[u,i]] then beginshortest[vetex[u,i]]:=shortest[u]+map[u,vetex[u,i]];if not flag[vetex[u,i]] thenbegininc(closed);x0[closed]:=vetex[u,i];flag[vetex[u,i]]:=true;end;end;flag[u]:=false;until open>=closed;end;六、背包问题1.尽量把容量为w的箱子装满varf:array[0..maxw]of boolean;weight:array[1..maxn]of longint;function p1:longint;vari,j:longint;beginfillchar(f,sizeof(f),0);f[0]:=true;for i:=1 to n dofor j:=w downto weight[i] dof[j]:=f[j] or f[j-weight[j]];i:=w;while not f[i] do dec(i);exit(i);end;2.在容量为w的箱子中装入物品使总价值最高varf:array[0..maxw]of longint;weight,value:array[1..maxn]of longint;function p2:longint;vari,j:longint;beginfillchar(f,sizeof(f),$FF);f[0]:=0;for i:=1 to n dofor j:=w downto weight[i] doif f[j-weight[i]]<>-1 thenf[j]:=max(f[j],f[j-weight[i]]+value[i]);j:=0;for i:=0 to w do j:=max(j,f[i]);exit(j);end;3.在满足两个量的限制(w,h)条件下使总价值最高typenode=recordw,h:longint;value:longint;end;varf:array[0..maxw,0..maxh]of longint;num:array[1..maxn]of node;function p3:longint;vari,j:longint;beginfillchar(f,sizeof(f),$FF);f[0,0]:=0;for i:=1 to n dofor j:=w downto num[i].w dofor k:=h downto num[i].h doif f[j-num[i].w,k-num[i].h]<>-1 thenf[j,k]:=max(f[j,k],f[j-num[i].w,k-num[i].h]+num[i].value);i:=0;for j:=0 to w dofor k:=0 to h do i:=max(i,f[j,k]);exit(i);end;。