写一发Floyed。处理多源最短路径问题。
题目连接:http://poj.org/problem?id=1125
Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题。
Floyd-Warshall算法的时间复杂度为O(N3),空间复杂度为O(N2)。
Floyd-Warshall算法的原理是动态规划。
设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。
若最短路径经过点k,则Di,j,k = Di,k,k − 1 + Dk,j,k − 1;
若最短路径不经过点k,则Di,j,k = Di,j,k − 1。
因此,Di,j,k = min(Di,k,k − 1 + Dk,j,k − 1,Di,j,k − 1)。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。(见下面的算法描述)
Floyd-Warshall算法的描述如下:
for k ← 1 to n do
for i ← 1 to n do
for j ← 1 to n do
if (Di,k + Dk,j < Di,j) then
Di,j ← Di,k + Dk,j;
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <math.h>
#include <algorithm>
using namespace std;
int map[102][102];
int dist[102][102];
int maxx[102];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n;
while(scanf(" %d",&n)!=EOF && n!=0)
{
int m;
memset(map,0x3f,sizeof(map));
memset(dist,0x3f,sizeof(dist));
for(int i=0; i<n; i++)
{
map[i][i] = 0;
dist[i][i] = 0;
}
for(int i=0; i<n; i++)
{
scanf(" %d",&m);
for(int j=0; j<m; j++)
{
int a,b;
scanf(" %d %d",&a,&b);
map[i][a-1] = b;
dist[i][a-1] = b;
}
}
for(int k=0; k<n; k++)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
}
}
}
memset(maxx,0,sizeof(maxx));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(dist[i][j]>maxx[i])
{
maxx[i] = dist[i][j];
}
}
}
int min = maxx[0];
int min_num = 0;
for(int i=1;i<n;i++)
{
if(maxx[i]<min)
{
min = maxx[i];
min_num = i;
}
}
if(min == 0x3f3f3f3f)
{
printf("disjoint\n");
}
else
{
printf("%d %d\n",min_num+1,min);
}
}
return 0;
}
参考: http://www.cnblogs.com/davidluo/articles/1799811.html