图论常用模板
来源:互联网 发布:加拿大留学费用 知乎 编辑:程序博客网 时间:2024/05/18 02:51
自己将最短路和最小生成树的模板打了一遍,存一下。
最短路:
Floyd:
//给定n个点,m条边,输出(1,n)最短路,时间复杂度O(n*n*n)。#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define spot 100int a[spot+10][spot+10];const int inf=0x3f3f3f3f;int main(){ int n,m,i,j,k,x,y,z; while(scanf("%d%d",&n,&m)!=EOF) { memset(a,0x3f,sizeof(a)); for(i=1; i<=n; i++) a[i][i]=0; for(i=1; i<=m; i++) scanf("%d%d%d",&x,&y,&z),a[x][y]=min(z,a[x][y]),a[y][x]=a[x][y]; for(k=1; k<=n; k++) for(i=1; i<=n; i++) for(j=1; j<=n; j++) a[i][j]=min(a[i][j],a[i][k]+a[k][j]); printf("%d\n",a[1][n]); } return 0;}
Dijkstra:
//迪杰斯特拉(无向图)给定n个点,m条遍,start起点,over终点,求(start,end)最短路,时间复杂度O(n*n)。#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define spot 1000int a[spot+10][spot+10],inf=0x3f3f3f3f,dis[spot+10],b[spot+10];int main(){ int n,m,start,over; while(scanf("%d%d",&n,&m)!=EOF) //n个点,m条遍 { scanf("%d%d",&start,&over); //给定起点start,终点over memset(b,0,sizeof(b)); int i,j,x,y,z; memset(a,0x3f,sizeof(a)); for(i=1; i<=n; i++) a[i][i]=0; for(i=1; i<=m; i++) scanf("%d%d%d",&x,&y,&z),a[x][y]=min(a[x][y],z),a[y][x]=a[x][y]; //可能会有重遍 for(i=1; i<=n; i++) dis[i]=a[start][i]; b[start]=1; for(i=1; i<n; i++) { int minn=inf,u; for(j=1; j<=n; j++) if(dis[j]<minn&&!b[j]) u=j,minn=dis[j]; b[u]=1; for(j=1; j<=n; j++) if(dis[j]>minn+a[u][j]&&a[u][j]<inf) dis[j]=minn+a[u][j]; } printf("%d\n",dis[over]); }}
bellman ford:
//贝尔曼 无向图 n个点,m条边,给定起点start,终点over,求(start,over)最短路,若无输出-1,,时间复杂度O(N*M)。#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define edge 10000 //边的条数int b[edge+10],dis[edge+10],inf=0x3f3f3f3f;struct stu{ int x,y,z;} c[edge+10];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int i,j,start,over; scanf("%d%d",&start,&over);//起终点 for(i=1; i<=m; i++) scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].z); //边 memset(dis,0x3f,sizeof(dis)); dis[start]=0; for(i=1; i<n; i++) for(j=1; j<=m; j++) { dis[c[j].y]=min(dis[c[j].x]+c[j].z,dis[c[j].y]); dis[c[j].x]=min(dis[c[j].y]+c[j].z,dis[c[j].x]); } printf("%d\n",dis[over]); } return 0;}
Spfa:
//无向图 贝尔曼的队列优化,给定n个点,m条边,起点start,终点over求(start,over)最短路#include<cstdio>#include<cstring>#include<queue>using namespace std;#define spot 100000 //点#define edge 1000000 //边struct stu{ int x,y,z;} a[2*edge+10];int dis[spot+10],first[spot+10],next1[2*edge+10],b[spot+10],inf=0x3f3f3f3f;int main(){ queue<int>q; int n,m,start,over,i,j,xx,yy,zz,k; while(scanf("%d%d%d%d",&n,&m,&start,&over)!=EOF) { j=0; memset(dis,0x3f,sizeof(dis)); memset(first,-1,sizeof(first)); memset(b,0,sizeof(b)); dis[start]=0; b[start]=1; for(i=1; i<=m; i++) { scanf("%d%d%d",&xx,&yy,&zz); a[++j].x=xx,a[j].y=yy,a[j].z=zz; next1[j]=first[a[j].x]; first[a[j].x]=j; a[++j].x=yy,a[j].y=xx,a[j].z=zz; next1[j]=first[a[j].x]; first[a[j].x]=j; } q.push(start); while(!q.empty()) { k=q.front(); q.pop(); b[k]=0; for(k=first[k]; k+1; k=next1[k]) { if(dis[a[k].y]>dis[a[k].x]+a[k].z) { dis[a[k].y]=dis[a[k].x]+a[k].z; if(!b[a[k].y]) q.push(a[k].y),b[a[k].y]=1; } } } int maxx=inf; printf("%d\n",dis[over]); } return 0;}
最小生成树:
Kruscal:
//Kruscal算法最小生成树 n个点,m条边,求最小长度#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define spot 100000 //点#define edge 1000000 //边struct stu{ int x,y,z;} a[edge+10];int b[spot+10];bool cmp(stu a,stu b){ return a.z<b.z;}int finds(int x){ int j,d=x; while(x!=b[x]) x=b[x]; while(b[d]!=x) j=d,d=b[d],b[j]=x; return x;}bool mix(int x,int y){ int fx=finds(x),fy=finds(y); if(fx!=fy) { b[fx]=fy; return 0; } return 1;}int main(){ int n,m,i; while(scanf("%d%d",&n,&m)!=EOF) { int sum=0,s=0; for(i=1; i<=n; i++) b[i]=i; for(i=1; i<=m; i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); sort(a+1,a+m+1,cmp); for(i=1; i<=m; i++) { if(!mix(a[i].x,a[i].y)) sum++,s+=a[i].z; if(sum==n-1) break; } printf("%d\n",s); } return 0;}
Prim:
//矩阵输入的prim 有n*n的矩阵,求最小生成树#include<stdio.h>#include<string.h>#define spot 1000const int inf=0x3f3f3f3f;int a[spot+10][spot+10],dis[spot+10],b[spot+10]; //a[][]存矩阵,b[]标记,dis[]距离int main(){ int n; while(scanf("%d",&n)!=EOF) { int sum=1,s=0,i,j; for(i=1; i<=n; i++) for(j=1; j<=n; j++) scanf("%d",&a[i][j]); memset(b,0,sizeof(b)); for(i=1; i<=n; i++) dis[i]=a[1][i]; dis[1]=0; b[1]=1; while(sum<n) { int minn=inf,u; for(i=1; i<=n; i++) if(!b[i]&&minn>dis[i]) minn=dis[i],u=i; b[u]=1,sum++,s+=dis[u]; for(i=1; i<=n; i++) if(!b[i]&&a[u][i]<dis[i]) dis[i]=a[u][i]; } printf("%d\n",s); } return 0;}
0 0
- 图论常用模板
- 图论常用模板
- 【原创】图论常用算法模板(1)
- 【原创】图论常用算法模板(2)
- 常用模板
- 常用的二分图模板 匈牙利算法
- 常用宏、模板
- 常用PHP模板大全
- DedeCMS模板常用标签
- Magento 常用模板
- Ant常用模板(转)
- Hibernate常用代码模板
- 二分法常用模板
- 常用sql脚本模板
- 数论所以常用模板
- 常用driver模板
- shopex常用模板
- 一些常用算法模板
- AFNetWorking3.0的简单封装
- 线段树,树状数组
- 还在繁琐的敲MVP接口和实现类吗,教你一秒搞定。
- xgboost在windows下的安装与使用
- 异或^的几个用处
- 图论常用模板
- NOI2016 之看题跑
- Error retrieving parent for item: No resource found that matches the given name 'android:W
- 敏捷软件开发 Agile software Development
- postgreSQL触发器
- 性能优化——布局优化
- HDU 5748 Bellovin(LIS)
- DialogInterface点击事件和View点击事件冲突问题
- Android 别人那里学习到的回调机制