您的位置:首页 > 其它

图算法补充(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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: