题目链接:http://acm.tju.edu.cn/toj/showp1075.html
题目大意:给你n个人的联系情况,对任意一个人,求出这个人发消息到其他n-1个人的时间,得到n-1个时间中的最大值,n个最大值中的最小值就是所求。如果网络不通,那就输出disjoint
思路:(一)n重dijkstra 我是这么叫的 因为起始点有n种情况 - -! 然后对每一个点 dijkstra 得出n个dist[]值,然后在n个dist[]值中选择最大的;最后再从所有得到的最大值中选择最小的;(二)Floyd 此种方法后续补上;
代码:
(一):n重dijkstra:
//每个顶点为起始点 dijkstra
#include <iostream>
#include <cstring>
#include <cstdlib>
#define INF 2000
using namespace std;
int map[101][101];
int dist[101];
int ans[101];
int visited[101];
int person, Time;
int dijkstra(int n)
{
int i,j,k,min,pos;
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++) //以每个点为顶点,做dijkstra遍历(做n次dijkstra遍历,每次遍历做n-1次for循环)
{
for(j=1;j<=n;j++)
dist[j]=map[i][j];
memset(visited,0,sizeof(visited));
visited[i]=1;
pos = i;
for(j=1;j<n;j++) //开始遍历,到其他点的最短距离
{
min = INF;
for(k=1;k<=n;k++) //找到下一个距离最近的点
{
if(!visited[k]&&dist[k]<min)
{
min = dist[k];
pos = k;
}
}
visited[pos]=1;//更新visited表
for(k=1;k<=n;k++) //更新dist表
{
if(!visited[k]&&dist[pos]+map[pos][k]<dist[k])
dist[k] = map[pos][k]+dist[pos];
}
}
ans[i]=0; //每次遍历后,保存最大的距离
for(j=1;j<=n;j++)
{
if(ans[i]<dist[j])
ans[i]=dist[j];
}
}
Time = INF;
person = 0;
for(i=1;i<=n;i++)//所有距离中,寻找最短的距离
{
if(ans[i]<Time)
{
Time = ans[i];
person = i;
}
}
if(Time<INF)
return 1;
else
return 0;
}
int main()
{
int num,n,i,j,k,p,t;
while(cin>>num)
{
if(num==0) break;
for(i=1;i<=num;i++)//初始化map
{
for(j=1;j<=num;j++)
{
if(i!=j) map[i][j] = INF;
else map[i][j]= 0;
}
}
for(i=1;i<=num;i++)
{
cin>>n;
for(j=1;j<=n;j++)
{
cin>>p>>t;
map[i][p] = t;
}
}
if(dijkstra(num))
cout<<person<<" "<<Time<<endl;
else
cout<<"disjoint"<<endl;
}
return 0;
}
(二)、Floyd: