链接:http://poj.org/problem?id=1125
题意:找到能最快把谣言传给所有人的那个人,然后再给出最后一个得知谣言的人所需最短的时间。如果不能传达,输出"disjoint"。
浅谈:若有n个Stockbroker,把每个Stockbroker作为一个源点,用Dijkstra求源点到各个点的最短路,然后求出最大的,这样操作n次。然后在n个最大值中选取最小值即(最后一个得知谣言的人所需最短的时间),时间复杂度为O(n^3)。这个我又用Floyd做了一下。一直不想用Floyd,是因为当初看Floyd时被它的路径存取吓到了,所以一直对它略有恐惧。但其实求最短路的过程Floyd是相当简单的,反而比Dijkstra简单多了。这次是因为看到很多人说用Floyd做最为简单,所以也想试一试。然后回到这个题,其实原理是一样的。区别在于Floyd的路径压缩只进行一次。接下来的操作与Dijkstar一样。把其中每个点作为源点搜一下最大值。最后再找其中的最小值。
//Dijkstra
#include<iostream>
#define eMAX 105
#define INF 100
using namespace std;
int edge[eMAX][eMAX];
int st_num,ed_num;
int dist[100];
int Dijkstra(int v)
{
int s[eMAX];
int i,j,tmin,tmax=0;
for(i=1;i<=st_num;i++)
{
dist[i]=edge[v][i];
s[i]=0;
}
dist[v]=0;
s[v]=1;
for(i=1;i<st_num;i++)
{
tmin=1000;
int u=v;
for(j=1;j<=st_num;j++)
{
if(!s[j]&&dist[j]<tmin)
{
tmin=dist[j];
u=j;
}
}
s[u]=1;
for(j=1;j<=st_num;j++)
if(!s[j]&&edge[u][j]>0)
{
if(dist[j]>edge[u][j]+dist[u])
{
dist[j]=dist[u]+edge[u][j];
}
}
}
for(i=1;i<=st_num;i++)
{
if(!s[i])
return 0;
else if(dist[i]>tmax)
tmax=dist[i];
}
return tmax;
}
int main()
{
int n,m,i,j;
int b,t,maxtime=INF,start;
while(cin>>n)
{
if(!n)return 0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
edge[i][j]=INF;
ed_num=0;
st_num=n;
for(i=1;i<=n;i++)
{
cin>>m;
for(j=1;j<=m;j++)
{
cin>>b>>t;
edge[i][b]=t;
ed_num++;
}
}
for(i=1;i<=st_num;i++)
{
t=Dijkstra(i);
if(t>0&&t<maxtime)
{
maxtime=t;
start=i;
}
}
if(maxtime<INF)cout<<start<<" "<<maxtime<<endl;
else cout<<"disjoint"<<endl;
}
return 0;
}