图论
来源:互联网 发布:php布尔类型 编辑:程序博客网 时间:2024/05/21 18:43
- 图论
- 图的储存
- 邻接矩阵
- 邻接表
- 最短路径
- floyd
- dijkstra
- 最小生成树
- Prim
- 图的储存
图论
图的储存
1.邻接矩阵
2.邻接表
struct tyc{int x,t,l,ne;} e[M];int v[N];void put (int x,int y,int l){ num++;e[num]={x,y,l,v[x]}; v[x]=num;}//枚举点x的所有出边for(int i=v[x];i;i=e[i].ne) i是出边
最短路径
floyd
//复杂度O(n^3)for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
dijkstra
需要注意的是:dijkstra无法用于处理带负权值的图
dijkstra的主要思路是分蓝白点,确定最短路长度的是白点,蓝点反之。
复杂度是相对比较优秀的O(n^2);
int S=1; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ if(dis[S][i]!=-1) d[i]=dis[S][i]; else d[i]=inf; } int k=0; vis[S]=true; d[0]=inf; for(int i=1;i<n;i++){ int mn=inf,k=0; for(int j=1;j<=n;j++) if(!vis[j] && d[j]<=mn) mn=d[j],k=j;//用变量mn筛出此时距离S最近的点 vis[k]=1; for(int j=1;j<=n;j++){ if(!vis[j] && dis[k][j]!=-1) d[j]=min(d[j],dis[k][j]); } }
上述代码,如果加上常数,其复杂度应是O(2*n^2)。
值的注意的是,通过堆进行优化的dijkstra复杂度更加优秀,可以达到O(n*(logn+n)),当数据很大的时候,会比上述复杂度优秀不少。
//堆优化后的dijstruct tyc { int id,v;//v 表示上文中的d[x] friend bool operator < (tyc a,tyc b) { return a.v>b.v; } };priority_queue<tyc> que;void Dijkstra(){ int S=1; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ if(dis[S][i]!=-1) d[i]=dis[S][i]; else d[i]=inf; } que.push((tyc){1,0}); rep(i,1,n){ que.push((tyc){i,d[i]}); } int x,y; d[0]=inf; while(!que.empty()){ x = que.top().id, y = que.top().v; que.pop(); if(vis[x]) continue; vis[x]=1; for(int j=1;j<=n;j++) { if(vis[j]) continue; if(dis[x][j]!=-1 && dis[x][j] < d[j]) { d[j] = dis[x][j]; que.push((tyc){j,d[j]}); } } }}
最小生成树
Prim
基本思路与Dijkstra相同
int Prim(){ int ans=0; int S=1; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ if(dis[S][i]!=-1) d[i]=dis[S][i]; else d[i]=inf; } int k=0; vis[S]=true; d[0]=inf; for(int i=1;i<n;i++){ int mn=inf,k=0; for(int j=1;j<=n;j++) if(!vis[j] && d[j]<=mn) mn=d[j],k=j;//用变量mn筛出此时距离S最近的点 vis[k]=1; ans+=d[k];//!!!!!!!!!!! for(int j=1;j<=n;j++){ if(!vis[j] && dis[k][j]!=-1) d[j]=min(d[j],dis[k][j]); } } return ans;}
堆优化版:
struct tyc { int id,v;//v 表示上文中的d[x] friend bool operator < (tyc a,tyc b) { return a.v>b.v; } };priority_queue<tyc> que;int Prim(){ int ans=0; int S=1; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ if(dis[S][i]!=-1) d[i]=dis[S][i]; else d[i]=inf; } que.push((tyc){1,0}); rep(i,1,n){ if(d[i]==inf) continue; que.push((tyc){i,d[i]}); } int x,y; d[0]=inf; while(!que.empty()){ x = que.top().id, y = que.top().v; que.pop(); if(vis[x]) continue; vis[x]=1; ans+=y; for(int j=1;j<=n;j++) { if(vis[j]) continue; if(dis[x][j]!=-1 && dis[x][j] < d[j]) { d[j] = dis[x][j]; que.push((tyc){j,d[j]}); } } }
0 0