Zju1082 谣言的传播

该博客探讨了一个关于信息传播的问题,金无怠试图通过在FBI中散布谣言来影响其运作。问题转化为在有向图中寻找最佳起点,以使所有节点能最快接收到消息。利用Floyd算法,可以找到两点间的所有最短路径,从而解决这个问题。博客提供了样例输入和输出,并附带了解决方案代码。
摘要由CSDN通过智能技术生成

Description

China历史最伟大的SPY金无怠潜入了美国的FBI,为了整掉这个罪恶的机构,他决定在FBI散布假消息。他首先选定FBI中的某一个职员,将谣言告诉他,然后这个人会将消息再告诉给每一个他认识的人,当然在这个过程中需要花费一定的时候。然后这些人又会把消息告诉给每一个他所认识的人。这样消息就可能传遍整个FBI,当然每个人知道这个消息的时间有先有后。我们希望最晚才知道这个消息的人他所需要的时间越短越好(设这个时间长度为T)。那么金无怠应该选择哪一个人做为消息的首发者呢?请输出这个人的编号及T。如果消息不能传遍FBI请输出"disjoint"
注意从职员A传播谣言给职员B的时间不一定等于从职员B传播谣言给职员A的时间。

Input

先给出FBI中有多少个职员,用数字N(N<=100)来代表。
接下来N行,用来描述这N个职员。
每一行给出这个职员他认识几个人,然后给出所认识的职员的编号及传消息给他所要花的时间.

Output

如题

Sample Input

3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2

Sample Output

3 2

题目大意:
给你一个有权值的有向图,现问从哪个点出发可以遍历整个图,并要求所花费的权值越少越好,如不能遍历则输出"disjoint"。

题解:
此题告诉了点的数据范围,并且也不大,最简便的方法则是Floyd算法,n^3是不会超时的,所以本题求出每两个点的最短路径,再去搜索最后得知消息的那个点,最后去作比较即可。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int v[101][101],d[101][101];
int t[101];
int n,m,x,y,N;
int main()
{
    memset(v,63,sizeof(v));//预处理
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&N);
        for(int j=1;j<=N;j++)
        {
            scanf("%d%d",&x,&y);
            v[i][x]=y;
        }
    }
    for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
        if(v[i][k]+v[k][j]<v[i][j])
        v[i][j]=v[i][k]+v[k][j];
    }//搜索最短路径
    int minn=1e9,sum;
    for(int i=1;i<=n;i++)
    {
        int maxx=0;
        for(int k=1;k<=n;k++)
        if(v[i][k]>maxx&&i!=k) 
        maxx=v[i][k];//找出最晚得知消息的权值,若不能到达则maxx自动赋值为最大值
        if(maxx<minn) minn=maxx,sum=i;//与当前最短路径作比较
    }
    if(minn==1e9)
    printf("disjoint");//若搜完后发现不能遍历整个图,则输出"disjoint"    
    else
    printf("%d %d",sum,minn);//否则输出最短路径及开始点
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值