图论算法-建图和最短路
来源:互联网 发布:黑帽seo劫持博客违法吗 编辑:程序博客网 时间:2024/06/18 11:13
建图方法:
详细参见http://blog.csdn.net/stay_accept/article/details/50886067
常见两种:
链接表法
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int N,M; struct node{ int to,w; node *next; }; struct edge{ node *first; }G[105]; //存第一条边int main(){ int i,j,x,y,z; scanf("%d%d",&N,&M); for(i=0;i<M;i++){ scanf("%d%d%d",&x,&y,&z); node *p=new node; p->to=y; p->w=z; p->next=G[x].first; //每条边连在当前节点的前一条边上 G[x].first=p; //形成一个链式储存结构,first为当前节点的最后 } //一条边 node *k; for(i=1;i<=N;i++){ //图的遍历 for(k=G[i].first;k!=NULL;k=k->next) printf("%d %d %d\n",i,k->to,k->w); } return 0; }
struct Node{int to;//终点 int cap;//容量int flow=0;int rev; //反向点int cost; //费用};typedef vector<Node>* Graph;void add_Node(Graph v,int from, int to, int cap,int cost) //加边 {Node nodefrom,nodeto;nodefrom.to = to, nodefrom.cap =cap,nodefrom.rev = v[to].size(),nodefrom.cost = cost;v[from].push_back(nodefrom);nodeto.to = from, nodeto.cap =cap, nodeto.rev = v[from].size()-1,nodeto.cost =cost;v[to].push_back(nodeto);}
最短路算法Dijkstra
//Dijkstra求单源最短路径 void Dijkstra(Graph G,int Vcount,int s,int path[],int dist[]){ //Vcount:顶点个数;s:开始结点;path[]用于返回由开始结点到相应结点的路径指示 int i,j,w,minc,dist[Vcount],mark[Vcount]; //mark记录是否访问过 memset(mark,0,Vcount); //开始都没有访问过 for(i=0;i<Vcount;i++){ dist[i]=G[s][i]; path[i]=s; } //初始化,不可达的话设置为无穷 mark[s]=1;path[s]=0;dist[s]=0; for(i=1;i<Vcount;i++){ minc=INFINITY; w=0; for(j=0;j<Vcount;j++) if(!mark[j] && minc>=dist[j]){ minc=dist[j]; w=j; //找出目前到达最小的边 } mark[w]=1; //访问 for(j=0;j<Vcount;j++) if(!mark[j] && G[w][j]!=INFINITY && dist[j]>dist[w]+G[w][j]){ dist[j]=dist[w]+G[w][j]; path[j]=w; //可松弛更新 } } } //注意:输入的图的边的权值必须非负(这是Dijkstra的局限性所在).floyd算法
void Floyd_Warshall(Graph G,int Vcount,Graph D,Graph P){ //D:D[i][j]表示从i到j的最短距离;P:P[i][j]表示从i到j的最短路径上的结点 int i,j,k; for(i=0;i<Vcount;i++) for(j=0;j<Vcount;j++){ D[i][j]=G[i][j]; P[i][j]=i; } //用这个算法最好用矩阵建图,初始化 for(i=0;i<Vcount;i++){ D[i][i]=0; P[i][i]=0; } //注意对角线初始化0 for(k=0;k<Vcount;k++) for(i=0;i<Vcount;i++) for(j=0;j<Vcount;j++) if(D[i][j]>D[i][k]+D[k][j]){ D[i][j]=D[i][k]+D[k][j]; P[i][j]=P[k][j]; } //比较所有i经过点k然后再到j的距离}
bellmanford 算法
bool BellmanFord( int s ) { for( int i = 0; i < n; i ++ ) dis[i] = inf; dis[s] = 0; for( int i = 0; i < n-1; i ++ ) //n-1次松弛 { for( int j = 0; j < n; j ++ ) //每一次对所有边操作 { if( dis[j] == inf ) continue; for( int k = 0; k < map[j].size(); k ++ ) { node u = map[j][k]; if( u.w != inf && dis[u.id] > dis[j] + u.w ) dis[u.id] = dis[j] + u.w; } } } for( int j = 0; j < n; j ++ ) { if( dis[j] == inf ) continue; for( int k = 0; k < map[j].size(); k ++ ) { node u = map[j][k]; if( u.w != inf && dis[u.id] > dis[j] + u.w ) return false; } } //检查负值圈 return true; }
SPFA 算法(bellman优化)
void SPFA(int v0) { memset(vis, false, sizeof(vis)); for(int i = 1; i <= n; i++) dis[i] = INF; dis[v0] = 0; queue <int> q; q.push(v0); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; int sz = vt[u].size(); for(int i = 0; i < sz; i++) { int v = vt[u][i].v; int w = vt[u][i].w; if(dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if(!vis[v]) { q.push(v); vis[v] = true; } } } } }
0 0
- 图论算法-建图和最短路
- 图论算法 最短路 Floyd
- 图论专题小结:最短路算法
- 图的最短路算法
- 图论入门之-----最短路之dijkstra 算法
- 【OI之路】03图论算法-1最短路之单源最短路(SPFA)
- 【OI之路】03图论算法-2最短路之全源最短路(Floyd)
- 图论模板-最短路
- 图论之最短路
- 图论之最短路
- 最短路:Dijkstra算法和Floyd算法
- 图算法系列之最短路算法Dijkstra(Java)
- HDU-2544 最短路(Dijkstra算法求无向图最短路模板题)
- 【DayDayUp】【算法_图_最短路_之一_Dijkstra和几种优化姿势】
- 最短路 Dijkstra 和 Floyd 算法
- 最短路算法学习总结和感悟
- 最短路算法:Dijkstra和Flody详解
- 最短路之弗洛伊德算法和模板
- selenium自动化测试框架搭建-思路,无代码
- 私活,永远解救不了自己屌丝的人生!
- Golang优雅退出http server
- springMVC 返回Json实体类属性自定义格式转换
- 虚拟机ubuntu16.04 安装caffe
- 图论算法-建图和最短路
- 入力規則とVisualforce DmlException
- Zephyr Kernel v1.7.0
- 【TX1学习与开发系列】交换空间与磁盘容量增加(二)
- SHA1算法实现及详解
- js基本知识比较系列二:DOM操作
- 离殇
- 题目1454:Piggy-Bank
- EXCEL-VBA:弹出对话框,打开文件(指定扩展名)