zoukankan      html  css  js  c++  java
  • 【9001】Internet消息发布

    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;
    }
    


     

  • 相关阅读:
    写在noi之前
    雅礼集训 Day8
    雅礼集训 Day6
    雅礼集训 Day5
    2017雅礼集训 Day4
    2017雅礼集训 Day2
    2017雅礼集训 Day1
    洛谷 P3426 [POI2005]SZA-Template
    Codeforces Round #368 DIV2 C.
    Educational Codeforces Round 16 D&E.
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632411.html
Copyright © 2011-2022 走看看