HOJ 1113 Stockbroker Grapevine (Floyd最短路)

来源:互联网 发布:r330打印机清零软件 编辑:程序博客网 时间:2024/04/30 02:15

题意:谣言在n个人之间传播,谣言从一个人传给另一个人需要一定时间(是有向图)。问谣言从哪个人开始传,传遍所有人所用时间最短(这里的时间指的是,传到最后一个人时所用的时间)。输出这个人的编号,及所需要时间。


分析:Dijkstra是用来求单源最短路的,而这里起点不确定。采用Floyd算法先对图进行收缩,O(n^3)的复杂度。对每个点,找到这个点做源点时,谣言传遍所有人所需要的“时间”,遍历所有点,找到最短的那个“时间”,复杂度为O(n^2)。


对于floyd算法:

算法描述:
(1) 用数组dis[i][j]来记录i,j之间的最短距离。初始化dis[i][j],若i=j则dis[i][j]=0,
若i,j之间有边连接则dis[i][j]的值为该边的权值,否则dis[i][j]的值为无穷大 。
(2) 对所有的k值从1到n,修正任意两点之间的最短距离,计算dis[i][k]+dis[k][j]的值,
若小于dis[i][j],则dis[i][j]= dis[i][k]+dis[k][j],否则dis[i][j]的值不变。

void Floyd(int dis[n+1][n+1],int n){int i,j,k;for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(dis[i][k]+dis[k][j]<dis[i][j])                {dis[i][j] = dis[i][k]+dis[k][j];                                }}

复杂度为O(n^3)



#include <iostream>#include <cstdio>#include <cstring>#define INF 0x7fffffffusing namespace std;int map[105][105];int main(){    int n;    while(scanf("%d",&n)!=EOF && n) {        for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)            {                map[i][j]=INF;       //这里用memset(map,INF,sizeof(map))的话,map总是被初始化成-1,求大神解释这是为什么?            }        }        for(int i=0; i<n; i++)map[i][i]=0;        for(int i=0; i<n; i++) {            int t;            scanf("%d",&t);            for(int j=0; j<t; j++) {                int p;                int d;                scanf("%d %d",&p,&d);                map[i][p-1]=d;            }        }        for ( int k = 0; k < n; ++k ) {          //floyd对图进行收缩,map[i][j]储存的内容变成了i,j间最短的距离            for ( int i = 0; i <n; ++i ) {                for ( int j = 0; j <n; ++j ) {                    if(map[i][k]!=INF && map[k][j]!=INF) {                        if ( map[i][k] + map[k][j] < map[i][j] ) {                            // 找到更短路径                            map[i][j] = map[i][k] + map[k][j];                        }                    }                }            }        }                int minn,start;        minn=INF;        for(int i=0; i<n; i++) {            int maxn=0;            for(int j=0; j<n; j++) {                maxn=max(map[i][j],maxn);  //以i为源点时,所需要消耗的“时间”(即传播到最远的那个人所需要时间)。      //因为前面已经对图进行了收缩,map[i][j]储存的已经是i到j的最短距离了            }            if(minn>maxn) {   //找到用时最短的那个源点                minn=maxn;                start=i;            }        }        if(minn==INF)printf("disjoint\n");        else {            printf("%d %d\n",start+1,minn);        }    }    return 0;}


原创粉丝点击