poj1125传播谣言(弗洛伊德,求最长路)

Stockbroker Grapevine
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 38541   Accepted: 21502

Description

Stockbrokers are known to overreact to rumours. You have been contracted to develop a method of spreading disinformation amongst the stockbrokers to give your employer the tactical edge in the stock market. For maximum effect, you have to spread the rumours in the fastest possible way. 

Unfortunately for you, stockbrokers only trust information coming from their "Trusted sources" This means you have to take into account the structure of their contacts when starting a rumour. It takes a certain amount of time for a specific stockbroker to pass the rumour on to each of his colleagues. Your task will be to write a program that tells you which stockbroker to choose as your starting point for the rumour, as well as the time it will take for the rumour to spread throughout the stockbroker community. This duration is measured as the time needed for the last person to receive the information.

Input

Your program will input data for different sets of stockbrokers. Each set starts with a line with the number of stockbrokers. Following this is a line for each stockbroker which contains the number of people who they have contact with, who these people are, and the time taken for them to pass the message to each person. The format of each stockbroker line is as follows: The line starts with the number of contacts (n), followed by n pairs of integers, one pair for each contact. Each pair lists first a number referring to the contact (e.g. a '1' means person number one in the set), followed by the time in minutes taken to pass a message to that person. There are no special punctuation symbols or spacing rules. 

Each person is numbered 1 through to the number of stockbrokers. The time taken to pass the message on will be between 1 and 10 minutes (inclusive), and the number of contacts will range between 0 and one less than the number of stockbrokers. The number of stockbrokers will range from 1 to 100. The input is terminated by a set of stockbrokers containing 0 (zero) people. 

Output

For each set of data, your program must output a single line containing the person who results in the fastest message transmission, and how long before the last person will receive any given message after you give it to this person, measured in integer minutes. 
It is possible that your program will receive a network of connections that excludes some persons, i.e. some people may be unreachable. If your program detects such a broken network, simply output the message "disjoint". Note that the time taken to pass the message from person A to person B is not necessarily the same as the time taken to pass it from B to A, if such transmission is possible at all.

Sample Input

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

Sample Output

3 2
3 10

题目传送门:点击打开链接

题目大意:你是一个谣言传播者,有n个经济人,每个经纪人会给自己的朋友传播消息,传播消息需要时间,然后让你选择一个经纪人,算出传播消息的最短时间。

思路:一开始想到最小生成树,以为时间复杂度会不够,后来意识到,最小生成树是很多个人一起走,而这道题我一开始以为是要一个一个的传播(如果我有很多朋友,我先和这个说,再和那个说),那这就不是最小生成树了。(后来发现题目不是这样的,是你在传播消息的时候,你的朋友围着听,而不是一个接一个)。但即便是这样,用最小生成树时间复杂度应该也会很高,因为要枚举起点。看了题解之后发现是用弗洛伊德先求出最短路,然后对于每一个起点i,所有的d【i】【j】中最大的一个,就是从这个起点开始传播到所有人的时间,所以对于每一个起点,遍历每一个终点,保存最小值就可以了,最小值是INF,说明有人是失联的,输出disjoint。

理解了题意就是水题了,上代码。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
#define ll long long
using namespace std;
const int maxn=110;
const int INF=0x3f3f3f3f;
int d[maxn][maxn],n;
int main() {
	while(scanf("%d",&n),n) {
		memset(d,INF,sizeof(d));
		for(int i=1;i<=n;i++){
			d[i][i]=0;
		int m;
		scanf("%d",&m);
		while(m--){
			int v,len;
			scanf("%d%d",&v,&len);
			d[i][v]=len;
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				for(int k=1;k<=n;k++){
					if(d[j][k]>d[j][i]+d[i][k]){
						d[j][k]=d[j][i]+d[i][k];
					}
				}
			}
		}
		int minn=INF;
		int p;
		for(int i=1;i<=n;i++){
			int maxx=0;
			for(int j=1;j<=n;j++){
				if(i==j)continue;
				maxx=max(d[i][j],maxx);
			}
			if(maxx<minn){
				minn=maxx;
				p=i;
			}
		}
		if(minn==INF)printf("disjoint\n");
		else printf("%d %d\n",p,minn);
	}
}

猜你喜欢

转载自blog.csdn.net/ysk850874665/article/details/80164363