zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

【9001】Internet消息发布

消息 发布 Internet
2023-09-14 09:03:46 时间

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\n",ans);
}

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    input_data();
    get_ans();
    output_ans();
    return 0;
}