zoj 1082 Stockbroker Grapevine(第一次写最短路径~~嘻嘻~)

昨天CW给我们讲了最短路径哈~~大致理解明白了~发了两道题。做做看吧。

 

这道题大致含义就是,让你求最短的传播路径使之可以传播到所有的人。

 

这个是双向的,输入:

3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2

 

3是人数,下来的行数就是人的编号。第一行就是第一个人可以传播的方法。第一个2是接下来输入的对数。2 4 代表可以用4分钟传播给2号,3 5 代表可以用5分钟传播给3号。。。下面一样。

 

这个用邻接矩阵写比较方便哈。把时间写到一个2维数组里,不能传播到的写INT_MAX,对角都是0;

 

用for循环将每个人(i)作为起点,然后算传播到每个人的时间,会得到一个dis[]数组,里面存有i号人传播到每个人的时间,求这时间的最大值,保存。然后求出循环n个人后这个时间最大值里面的最小值,如果有传播不到的,输出"  disjoint  "。否则输出从几号开始传播 以及最短传播到所有人的时间。

 

#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <limits.h> int main(void) { int num,pair,i,j,x,n,now,k; int hash[1000]; int dis[100]; int map[100][100]; int mmax,max,number; int flag; int temp = 1; while( scanf("%d",&num) && num ) { max = INT_MAX; for(i=0; i<=num; i++) for(j=1; j<=num;j++) map[i][j] = INT_MAX; for(i=1; i<=num; i++) //建立邻接矩阵map { scanf("%d",&pair); for(j=1; j<=pair; j++) { scanf("%d %d",&x,&n); map[i][x] = n; } map[i][i] = 0; } max = INT_MAX; for(i=1; i<=num; i++) { memset(hash, 0 , sizeof(hash));//hash表状态,是否不能更新了,因为num个数,所以每次需要清零 for(j=1; j<=num; j++) //dis表示距离,全部清为最大值 dis[j] = INT_MAX; hash[i] = 1; now = i;dis[now] = 0; flag = 1; for(j=1; j<=num ; j++) { mmax = INT_MAX; for(k=1; k<=num ; k++) if( map[now][k]!=INT_MAX && dis[k] > dis[now] + map[now][k] )//如果i到k的距离比i到now加now到k的距离大,更新之 {//需要判断是否为INT_MAX,否则会越界 dis[k] = dis[now] + map[now][k]; } for(k=1; k<=num; k++)//寻找更新后的路径中最小的,即为下一个now if( !hash[k] && mmax > dis[k] ) { mmax = dis[k]; now = k; } hash[now] = 1;//标记1说明已经作为now更新其它了 } for(j=1; j<=num && flag; j++) if(dis[j] == INT_MAX) //判断是否能到达所有的人,如果经过上面的循环亦然有dis[j]==INT_MAX flag = 0; //说明以当前i出发不可取 temp = 0; if( flag ) { for(j=1; j<=num; j++) { if( dis[j] > temp )//如果i能传播到所有的人,寻找dis中最大值即为传播到所有人的时间 { temp = dis[j]; } } if( temp < max ) //找经过最外层循环得到的这些最大值中的最小值 { max = temp; number = i; } } } if( max == INT_MAX) printf(" disjoint /n"); else printf("%d %d/n",number,max); } system("pause"); return 0; }

你可能感兴趣的:(zoj 1082 Stockbroker Grapevine(第一次写最短路径~~嘻嘻~))