图算法补充(SPFA,最长路径)
2015-07-29 19:53
387 查看
1. SPFA(Shortest Path Faster Algorithm)
1994年,西南交通大学的段凡丁发表了SPFA,SPFA在Bellman-Ford算法的基础上加上一个队列优化,减少了冗余的松弛操作。
关于最短路径的SPFA快速算法(段凡丁):http://www.cnki.com.cn/Article/CJFDTotal-XNJT402.015.htm
wiki:https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm
2. 图的最长路径
(1)Bellman-Ford算法、Floyd-Warshall算法:将图中边的权重变为原来的相反数
(2)DAG(Directed Acyclic Graph,有向无环图):拓扑排序+动态规划
AOV(Activity On Vertex)网
AOE(Activity On Edge)网的关键路径
e(i)e(i)表示活动aia_i的最早开始时间,l(i)l(i)表示活动aia_i的最晚开始时间。
ve(i)ve(i)表示事件viv_i的最早发生时间,vl(i)vl(i)表示事件viv_i的最晚发生时间。
u→ai=wve(i)=ve(u)l(i)=vl(v)−wve[0]=0ve[v]=max(u,v)∈E{ve[u]+w},v=1,2,⋯,n−1vl[n−1]=ve[n−1]vl[u]=min(u,v)∈E{vl[v]−w},u=n−2,n−1,⋯,0\begin{array}{l}
u\mathop \to \limits^{{a_i} = w} v\\
e(i) = ve(u)\\
l(i) = vl(v) - w\\
ve[0] = 0\\
ve[v] = \mathop {\max }\limits_{(u,v) \in E} \{ ve[u] + w\} ,v = 1,2, \cdots ,n - 1\\
vl[n - 1] = ve[n - 1]\\
vl[u] = \mathop {\min }\limits_{(u,v) \in E} \{ vl[v] - w\} ,u = n - 2,n - 1, \cdots ,0
\end{array}
1994年,西南交通大学的段凡丁发表了SPFA,SPFA在Bellman-Ford算法的基础上加上一个队列优化,减少了冗余的松弛操作。
关于最短路径的SPFA快速算法(段凡丁):http://www.cnki.com.cn/Article/CJFDTotal-XNJT402.015.htm
wiki:https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm
#include<iostream> #include<vector> #include<queue> using namespace std; struct Node { int v,w; Node *next; Node(int x,int y):v(x),w(y),next(0){} }; struct Graph { int VNum,ENum; vector<Node *> Adj; }; void createGraph(Graph &G) { cin>>G.VNum>>G.ENum; for(int i=0;i<G.VNum;++i)G.Adj.push_back(0); for(int i=0;i<G.ENum;++i) { int u,v,w; cin>>u>>v>>w; Node *p=new Node(v,w); p->next=G.Adj[u]; G.Adj[u]=p; } } vector<int> SPFA(Graph G,int s) { vector<int> d(G.VNum,INT_MAX); vector<bool> flag(G.VNum,false); d[s]=0; queue<int> Q; Q.push(s); flag[s]=true; while(!Q.empty()) { int u=Q.front(); Q.pop(); flag[u]=false; for(Node *p=G.Adj[u];p;p=p->next) { int v=p->v,w=p->w; if(d[u]+w<d[v]) { d[v]=d[u]+w; if(!flag[v]) { Q.push(v); flag[v]=true; } } } } return d; } //输入 //5 10 //0 1 10 //0 3 5 //1 2 1 //1 3 2 //2 4 4 //3 1 3 //3 2 9 //3 4 2 //4 0 7 //4 2 6 // //输出 //0 8 9 5 7 int main() { Graph G; createGraph(G); int s=0; vector<int> d=SPFA(G,s); for(int i=0;i<d.size();++i)cout<<d[i]<<' '; cout<<endl; return 0; }
2. 图的最长路径
(1)Bellman-Ford算法、Floyd-Warshall算法:将图中边的权重变为原来的相反数
(2)DAG(Directed Acyclic Graph,有向无环图):拓扑排序+动态规划
AOV(Activity On Vertex)网
AOE(Activity On Edge)网的关键路径
e(i)e(i)表示活动aia_i的最早开始时间,l(i)l(i)表示活动aia_i的最晚开始时间。
ve(i)ve(i)表示事件viv_i的最早发生时间,vl(i)vl(i)表示事件viv_i的最晚发生时间。
u→ai=wve(i)=ve(u)l(i)=vl(v)−wve[0]=0ve[v]=max(u,v)∈E{ve[u]+w},v=1,2,⋯,n−1vl[n−1]=ve[n−1]vl[u]=min(u,v)∈E{vl[v]−w},u=n−2,n−1,⋯,0\begin{array}{l}
u\mathop \to \limits^{{a_i} = w} v\\
e(i) = ve(u)\\
l(i) = vl(v) - w\\
ve[0] = 0\\
ve[v] = \mathop {\max }\limits_{(u,v) \in E} \{ ve[u] + w\} ,v = 1,2, \cdots ,n - 1\\
vl[n - 1] = ve[n - 1]\\
vl[u] = \mathop {\min }\limits_{(u,v) \in E} \{ vl[v] - w\} ,u = n - 2,n - 1, \cdots ,0
\end{array}
#include<iostream> #include<vector> #include<stack> using namespace std; struct Node { int v,w; Node *next; Node(int x,int y):v(x),w(y),next(0){} }; struct Graph { int VNum,ENum; vector<Node *> Adj; }; void createGraph(Graph &G) { cin>>G.VNum>>G.ENum; for(int i=0;i<G.VNum;++i)G.Adj.push_back(0); for(int i=0;i<G.ENum;++i) { int u,v,w; cin>>u>>v>>w; Node *p=new Node(v,w); p->next=G.Adj[u]; G.Adj[u]=p; } } vector<int> GetInDegree(Graph G) { vector<int> indegree(G.VNum,0); for(int u=0;u<G.VNum;++u) { for(Node *p=G.Adj[u];p;p=p->next) { int v=p->v; ++indegree[v]; } } return indegree; } void TopoSort(Graph G,stack<int> &T,vector<int> &ve) { vector<int> indegree=GetInDegree(G); stack<int> S; for(int u=0;u<G.VNum;++u) { if(indegree[u]==0)S.push(u); } while(!S.empty()) { int u=S.top(); S.pop(); T.push(u); for(Node *p=G.Adj[u];p;p=p->next) { int v=p->v,w=p->w; if(--indegree[v]==0)S.push(v); if(ve[u]+w>ve[v])ve[v]=ve[u]+w; } } } void CriticalPath(Graph G) { stack<int> T; vector<int> ve(G.VNum,0); TopoSort(G,T,ve); vector<int> vl(G.VNum,ve[G.VNum-1]); while(!T.empty()) { int u=T.top(); T.pop(); for(Node *p=G.Adj[u];p;p=p->next) { int v=p->v,w=p->w; if(vl[v]-w<vl[u])vl[u]=vl[v]-w; } } for(int u=0;u<G.VNum;++u) { for(Node *p=G.Adj[u];p;p=p->next) { int v=p->v,w=p->w; int ee=ve[u]; int el=vl[v]-w; char tag=(ee==el)?'*':' '; cout<<u<<"->"<<v<<' '<<w<<' '<<ee<<' '<<el<<' '<<tag<<endl; } } } //6 8 //0 1 3 //0 2 2 //1 3 2 //1 4 3 //2 3 4 //2 5 3 //3 5 2 //4 5 1 int main() { Graph G; createGraph(G); CriticalPath(G); return 0; }
相关文章推荐
- POJ 题目3252 Round Numbers(数位DP)
- 在线最优化求解(Online Optimization)之五:FTRL
- 学习pca的一点小小感悟
- java基础第三讲——顺序、条件、循环结构
- python模拟新浪微博登陆功能(新浪微博爬虫)
- 《深入浅出数据分析》读后详解
- 向lCD_1602显示屏输入字符
- 在线最优化求解(Online Optimization)之四:RDA
- 在线最优化求解(Online Optimization)之三:FOBOS
- [html5]练习canvas 扔骰子
- 弹出窗
- python显示灰度图
- 用C#写一个多进程监控自动关机工具
- linux vi 编辑后保存
- 无法连接到local及运行错误"91"解决办法
- 简单图片浏览器
- Android开发中Service与Thread几点思考
- JDBC详解
- //1+2^1-1+...+2^20-1
- //1-1/2+1/3-...+1/n