求两点间最短路的最大值,首先会想到floyd,但是o(n^3)会超时,所以采用spfa,o(n^2)..
spfa算法步骤:(队列的应用提高了bellman-ford的效率)
1,建一个队列,用vis数组记录某点是否在队列中,用dis数组记录源点到某点的距离;
2,将源点放入队列中,标记
3,当队列非空时,从队列中弹出一个元素,以该元素为中心向外扩展,如果边edge(u,v)存在,且dis[v]>dis[u]+edge[u][v],则更新dis[v];同时,判断v是否在队列中,若不在,就入队。
4.如果要判环的话,应该再加一个out数组,用来记录每个点出队的次数,如果某一点出对次数大于n-1次
就说明存在环。(转)
代码:
#include <stdio.h> //spfa算法
#include <iostream>
#include <cstring>
#include <string.h>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x7ffffff
#define pi acos(-1)
using namespace std;
string s1,s2,s;
int n,m;
map<string,int>pos;
vector<int>v[1010];
int dis[1005];
int vis[1005];
queue<int>q;
int ans;
void bfs(int x)
{
for(int j=1; j<=n; j++)
dis[j]=INF;
memset(vis,0,sizeof(vis));
dis[x]=0;
vis[x]=1;
q.push(x);
while(!q.empty())
{
int p=q.front();
q.pop();
vis[p]=0;
for(int i=0; i<v[p].size(); i++)
{
if(dis[v[p][i]] > dis[p]+1)
{
dis[v[p][i]]=dis[p]+1;
if(!vis[v[p][i]])
q.push(v[p][i]);
}
}
}
for(int j=1; j<=n; j++)
ans=max(ans,dis[j]);
}
int main()
{
while(scanf("%d",&n),n)
{
pos.clear();
for(int i=1; i<=n; i++)
v[i].clear();
for(int i=1; i<=n; i++)
{
cin>>s;
pos[s]=i;
}
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
cin>>s1>>s2;
int a=pos[s1],b=pos[s2];
v[a].push_back(b);
v[b].push_back(a);
}
ans=0;
for(int i=1; i<=n; i++)
{
bfs(i);
}
if(ans==INF)ans=-1;
printf("%d\n",ans);
}
return 0;
}