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);
	}
}

發佈了40 篇原創文章 · 獲贊 0 · 訪問量 5206
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章