Time Limit: 1 second
Memory Limit: 256 MB
问题描述
设Internet上有N个站点,通常从一个站点发送消息给其他N-1个站点,需依次发送N-1次。这样从一个站点发布消息传遍N个站点时
,可能要较长时间。而当一个站点发布消息给另一个站点后,已获得消息的这两个站点就可以 发布消息给另外两个站点,此后
就有四个站点可以同时发布消息,这种发布消息方法应该会缩短消息传遍N个站点的时间。
请您编一个程序,设从每一个站点都可以向其他N-1个站点同时发送消息,编程求出从第一个站点开始发布消息传遍N个站点的
最短时间。
Input
由文件data.in输入数据,文件的第一行是Internet上的站点数N(1<=N<=100),第二行起是邻接矩阵严格的下三角部分
,各行是整数或字符X。A(I, J)表示从I站点发送消息给J站点所需要的时间。假设网络是无方向的,故A(I, J)=A(J, I),当A
(I, J)=-1时,表示从站点I不能直接向站点J发送消息;A(I,I)=0表示没有必要自己给自己送消息(1<=I<=N),严格的下三
角阵表示如下:
A(2, 1)
A(3, 1), A(3, 2)
A(4, 1), A(4, 2), A(4, 3)
┇
A(N, 1), A(N, 2)……A(N, N-1)
Output
从屏幕上输出,输出只有一行,它是一个非负整数,若为0表示无解,非0表示合符题意的最小整数。
Sample Input
5 50 30 5 100 20 50 10 -1 -1 10
Sample Output
35
【题解】
算出站点1到各个站点的最短路径。然后找到站点1到各个站点的最短距离的最大值。
这个最大值就是所求的最短时间。
题目说的意思就是说有n-1个人在站点1,然后分别走到其他n-1个站点,那最短的时间就是最晚到的那个人,只要每个人都走最优的路线,那么最晚的那个人所用的时间就是最短的了。
用dijkstra算法。
【代码】
#include <cstdio> #include <cstring> int n,t[110][110],a[110][110],mt[110],ans = 0; bool bo[110]; void input_data() { memset(a,0,sizeof(a)); memset(bo,true,sizeof(bo)); scanf("%d",&n); for (int i = 1;i <= n;i++) mt[i] = 2100000000; for (int i = 2;i <= n;i++) //输入数据 for (int j = 1;j <=i-1;j++) { scanf("%d",&t[i][j]); if (t[i][j]!=-1) //如果不等于-1,则表示i和j是连通的 { a[i][++a[i][0]] = j;//记录i的出度信息 a[j][++a[j][0]] = i;//记录j的出度信息 t[j][i] = t[i][j];//全值是双向的。 } } } void get_ans() { mt[1] = 0; for (int i = 1;i <= n;i++) //进行dijkstra算法。 { int k = 0,min_n = 2100000000; for (int j = 1;j <= n;j++) //先找到mt最小的值 if (bo[j] && (mt[j] < min_n)) //同时还要是之前没找过的位置 min_n = mt[j],k = j; if (k == 0) break;//如果没有找到这样的位置 那么就不再找,结束就好 bo[k] = false; for (int j = 1;j <= a[k][0];j++) //根据其出度信息,更新到出度的最优解。 if (mt[a[k][j]] > mt[k] + t[k][a[k][j]]) mt[a[k][j]] = mt[k] + t[k][a[k][j]]; } for (int i = 1;i <= n;i++) //找到最优解中的最大值。这个值就是答案。 if (mt[i]!=2100000000 && mt[i] > ans) ans = mt[i]; } void output_ans() { printf("%d ",ans); } int main() { //freopen("F:\rush.txt","r",stdin); input_data(); get_ans(); output_ans(); return 0; }