Floyd算法,以动态规划为理论基础,poj1125

Floyd是用于查找图中每一对顶点之间的最短距离,是以动态规划为基础的算法;

基本思想:若现在要求vi到vj的最短路径,设vi到vj的路径dis(vi,vj)即为最短路径,可将dis(vi,vj)与dis(vi,v0,vj)进行比较(其中v0表示vi到vj之间的一个结点,即vi能通过v0到达vj),取较小值,然后在此较小值上再增加一个结点v1,将dis(vi,...,v1,...,vj)和已经得到的从vi到vj的较小值比较,取较小值;再增加一个结点v2,以此类推,最终便可得到vi到vj的最短路径。

由上述可得出递推公式(arc表示i到j的直接路径,若没有,用一个极大值0x3f3f3f3f代替):

上代码:

void floyd(int n){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(a[i][k]+a[k][j]<a[i][j]){
                    a[i][j] = a[i][k]+a[k][j];
                }
            }
        }
    }
} 

接下来上一个例题,poj1125.

题目描述:炒股为了获得高收益,投资人需要释放谣言引起恐慌,投资人目前有几个手下专门用于释放谣言,最后要使得他们都知道这个谣言,要求输入这几个手下之间互相传递信息的时间,信息可同时传递,输出使他们都知道消息的最短时间方案(以谁为消息源,时间是多少).

输入:

包含多个输入样例,以0结束,开头输入一个n表示n个手下,接下来输入n行,每行开头输入一个m表示这个手下与多少个人有联系,紧接着输入m组数据表示这个手下与哪个手下有联系以及传播时间

输出:

消息源手下编号,最短时间

样例输入:

3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2
5
3 4 4 2 8 5 3
1 5 8
4 1 6 4 10 2 7 5 2
0
2 2 5 1 5
0
样例输出:
3 2
3 10

分析:很明显此题要求的是,从一个结点出发到其他所有结点的最短路径,且可在同一时间进行传播,那么首先要用floyd求出每个结点之间的最短路径,
由于可在同一时间进行传播这一条件,最终的完成时间肯定是这个结点到其他节点最短路径的最大值,那么只需找出这些对大致当中的最小值便是最短时间,并记录对应下标便是消息源
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
const int MAX = 0x3f3f3f3f;
int a[105][105];

/*
poj 1125
floyd算法 
*/
void floyd(int n){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(a[i][k]+a[k][j]<a[i][j]){
                    a[i][j] = a[i][k]+a[k][j];
                }
            }
        }
    }
} 

int main(){
    int n;
    int res;
    while(cin>>n,n!=0){
        int min=0x3f3f3f3f;
        memset(a,MAX,sizeof(a));
        for(int i=1;i<=n;i++){
            int m;
            cin>>m;
            for(int j=0;j<m;j++){
                int temp;
                cin>>temp;
                cin>>a[i][temp];
            }
        }
        floyd(n);
        for(int i=1;i<=n;i++){
            int max=0;
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                if(a[i][j]>max){
                    max=a[i][j];
                }
            }
            if(max<min){
                min=max;
                res=i;
            }
        }
        cout<<res<<" "<<min<<endl;
//        for(int i=1;i<=n;i++){
//            for(int j=1;j<=n;j++){
//                cout<<a[i][j]<<" ";
//            }
//            cout<<endl;
//        } 
    }
    return 0;
} 

 

posted on 2017-09-29 15:43  T~Z  阅读(557)  评论(0编辑  收藏  举报