最近在练习Dijkstra算法,百度了下找到了北大OJ上的这一题,刚开始一看这英文头都大了,然后结合输入输出粗略地理解了下题意。可是写了好久还是不能写出来。。。睡了一个晚上,早上起来写了下终于过了样例,提交了下,WA!!!纠结!!!然后就去网上找下别人的正解,一看,原来是我的英语水平太差了。。。
题意大致是这样的:输入有C个Stockbroker,每一个Stockbroker可以将信息传给其他的n个Stockbrokers(两个人之间的传递信息的速度是单向的,不是A能传给B,B一定就能传给A,因此Tab不一定等于Tba),现在叫你求从哪个人开始传递,使从开始传递到最后一个人收到信息之间的时间最短,并输出第一个人的编号和传递的时间。
解题思路:就是算出从每一个人开始传递至全部人的最短时间,然后找出最小的那组数据就可以了。
题目链接:http://poj.org/problem?id=1125
以下是我的代码,仅供参考,当然这题还可以用其他的方法解决。
#include<stdio.h>
#define MAX 1000000
int map[105][105];//构图
int shortest=MAX;//记录最短路径
int start=1;//标记起点
void dijkstra(int beg,int c,int dis[105],int s[105] )
{
int i,j,num,min,temp;
int kaishi=beg;
num=1;//num表示已经有多少个点在最短路径中了
dis[beg]=0;
for(i=1;i<=c;i++)
while(num!=c)//当num==c时,说明找出了从kaishi这个起点出发的最短路径
{
min=MAX;
s[beg]=0;
for(i=1;i<=c;i++)
{
if(s[i]==1)
dis[i]=dis[i]<(dis[beg]+map[beg][i])?dis[i]:(dis[beg]+map[beg][i]);
if(s[i]==1 && min>dis[i])
{
min=dis[i];
temp=i;
}
}
if(min==MAX)
break;
beg=temp;
num++;
}
if(num==c && shortest>dis[temp])
{
shortest=dis[temp];
start=kaishi;
}
return ;
}
int main()
{
int a,b,c,n,i,j,min;
int path[105],mark[105],path1[105],mark1[105];
while(scanf("%d",&c)!=EOF && c!=0)
{
shortest=MAX;
min=MAX;
for(i=1;i<=c;i++)//列表的初始化以及数组的初始化
{
for(j=1;j<=c;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=MAX;
}
path[i]=path1[i]=MAX;
mark[i]=mark1[i]=0;
}
for(i=1;i<=c;i++)//数据的输入
{
scanf("%d",&n);
for(j=1;j<=n;j++)
{
scanf("%d %d",&a,&b);
map[i][a]=b;
}
mark[i]=mark1[i]=1;
}
for(i=1;i<=c;i++)
{
dijkstra(i,c,path1,mark1);
for(j=1;j<=c;j++)
{
path1[j]=path[j];
mark1[j]=mark[j];
}
}
if(shortest!=MAX)
printf("%d %d\n",start,shortest);
else
printf("disjoint\n");
}
return 0;
}