POJ 1125 Stockbroker Grapevine 最短路folyd算法

在明白folyd算法的前提下。。感觉这题题意比写法更难,题意:有n个人要散布谣言,每个人都可以定向的向若干个人传播谣言,同时需要花费若干时间,现在要让一个谣言能够传递到整个n个人的群体,问从哪个人开始这个谣言可以尽量快的传遍整个群体?传遍整个群体所用时间的定义是,从起始者开始传递,到整张图最后一个人接到谣言为止。

如果有的人永远无法被谣言传播到,则输出disjoint

翻译成图论的话就是,n个节点的带正权有向图,判断其是否为连通图,并寻找各节点作为源点时的各个节点间最短路的最大值的最小值。

这就是folyd算法了,先由input构建这张有向图,其次用folyd算法统计每个节点到所有节点的时间,即生成最短路。

再对于每个节点,考虑其到其他所有节点的最短时间,其中最大值就是从该节点出发到达整张图所需的时间(这个不难理解,对于源点u,如果到目的点v的最短路时间最长,说明这段时间内足以让谣言传给v和其他的人),那么这n个人的时间取最小值即为答案

poj的数据居然没有包括进整图不是连通图的情况,即“disjoint”的情况,这个。。我写的时候也忘写了,就迷迷糊糊的1A了...

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <string>
#include <cstdlib>
#include <vector>
#include <cmath>
//#define file
using namespace std;
#define MAX (1<<26)
int n;
int mp[110][110];
void init()
{
    for(int i=0; i<110; i++)
    {
        for(int j=0; j<110; j++)
        {
            mp[i][j]=MAX;
            if(i==j)mp[i][j]=0;
        }
    }
}
void folyd()
{
    //using the mind of folyd algorithm
    //for each path between node i and j
    //we update its length through the node k between i and j 
    for(int k=1; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {

                if(mp[i][k]+mp[k][j]<mp[i][j])
                {
                    mp[i][j]=mp[i][k]+mp[k][j];
                }

            }
        }
    }
}

int main()
{
    while(cin>>n)
    {
        int e=0;
        init();
        if(n==0)break;
        for(int i=1; i<=n; i++)
        {
            int num;
            cin>>num;
            int des,cost;
            while(num--)
            {
                cin>>des>>cost;
                mp[i][des]=cost;
            }
        }
        folyd();
        int ans=0;
        int anst=MAX;
        for(int i=1; i<=n; i++)
        {
            int tmp=0;
            for(int j=1; j<=n; j++)
            {
                tmp=max(mp[i][j],tmp);
                //even when we can't match these two points we should add it
                //which stands for "unreachable"
            }
            if(tmp==MAX)
            {
                e++;
            }
            if(tmp<anst&&tmp!=-1&&tmp!=0)
            {
                anst=tmp;
                ans=i;
            }
        }
        if(e==n)
            cout<<"disjoint"<<endl;
        else
            cout<<ans<<" "<<anst<<endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值